ethyca-fides 2.72.3rc1__py2.py3-none-any.whl → 2.73.0__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ethyca-fides might be problematic. Click here for more details.

Files changed (317) hide show
  1. {ethyca_fides-2.72.3rc1.dist-info → ethyca_fides-2.73.0.dist-info}/METADATA +2 -2
  2. {ethyca_fides-2.72.3rc1.dist-info → ethyca_fides-2.73.0.dist-info}/RECORD +270 -258
  3. fides/_version.py +3 -3
  4. fides/api/alembic/migrations/versions/a55e12c2c2df_add_tagging_instructions_to_data_.py +29 -0
  5. fides/api/api/v1/endpoints/generic_overrides.py +70 -1
  6. fides/api/models/privacy_preference.py +1 -0
  7. fides/api/models/sql_models.py +3 -0
  8. fides/api/schemas/taxonomy_extensions.py +8 -0
  9. fides/api/service/async_dsr/strategies/async_dsr_strategy_polling.py +1 -0
  10. fides/api/service/connectors/query_configs/saas_query_config.py +141 -78
  11. fides/api/service/connectors/saas_connector.py +45 -43
  12. fides/api/service/privacy_request/request_service.py +1 -1
  13. fides/api/util/saas_util.py +27 -1
  14. fides/config/execution_settings.py +1 -1
  15. fides/ui-build/static/admin/404.html +1 -1
  16. fides/ui-build/static/admin/_next/static/6kEWO-NXzxn1tvUedYFei/_buildManifest.js +1 -0
  17. fides/ui-build/static/admin/_next/static/chunks/{1099-d1b22e891705eaf8.js → 1099-fa8b82f521b23cce.js} +1 -1
  18. fides/ui-build/static/admin/_next/static/chunks/{1115-584dac093cef6cc3.js → 1115-d7ce851b36722c41.js} +1 -1
  19. fides/ui-build/static/admin/_next/static/chunks/{1437-4604a69888906ec0.js → 1437-9dd64c20d38667df.js} +1 -1
  20. fides/ui-build/static/admin/_next/static/chunks/155-1c80b19f58f44a0c.js +1 -0
  21. fides/ui-build/static/admin/_next/static/chunks/{1817-bfe4139324aa0279.js → 1817-0de0312294019817.js} +1 -1
  22. fides/ui-build/static/admin/_next/static/chunks/{1975.50599b6774562644.js → 1975.6ca0e76b5a3d1955.js} +1 -1
  23. fides/ui-build/static/admin/_next/static/chunks/{2040-8eead9d29546a50f.js → 2040-a18cc21821e2d121.js} +1 -1
  24. fides/ui-build/static/admin/_next/static/chunks/{2397-92f628c53688925b.js → 2397-16820a09e8ebfe33.js} +1 -1
  25. fides/ui-build/static/admin/_next/static/chunks/2921-a5dac2eacdcc32ff.js +1 -0
  26. fides/ui-build/static/admin/_next/static/chunks/2962-342ad1b4ab402ded.js +1 -0
  27. fides/ui-build/static/admin/_next/static/chunks/{3377-80612c111e047cb6.js → 3377-c2c9eb177bec8719.js} +1 -1
  28. fides/ui-build/static/admin/_next/static/chunks/3446-f40c352c43ac950c.js +1 -0
  29. fides/ui-build/static/admin/_next/static/chunks/{3696-e4abb6a922b954a2.js → 3696-21e3dec6c2023875.js} +1 -1
  30. fides/ui-build/static/admin/_next/static/chunks/{3700-1f9f6e5ebfa3ab0a.js → 3700-a2903cd95b8a27cb.js} +1 -1
  31. fides/ui-build/static/admin/_next/static/chunks/{3772-b945c6839e43c753.js → 3772-bb84842df51d3f3f.js} +1 -1
  32. fides/ui-build/static/admin/_next/static/chunks/3873-d759bbe7137ae8c2.js +1 -0
  33. fides/ui-build/static/admin/_next/static/chunks/{3923-c1e41661ebf57178.js → 3923-7f0aa36c9e09cedf.js} +1 -1
  34. fides/ui-build/static/admin/_next/static/chunks/{401-c2f1e4ea077f1f26.js → 401-874303feb3899562.js} +1 -1
  35. fides/ui-build/static/admin/_next/static/chunks/{4496-8204168bae78092d.js → 4496-903c81292ffd8f91.js} +1 -1
  36. fides/ui-build/static/admin/_next/static/chunks/4817-d0cc100f259b3c2e.js +1 -0
  37. fides/ui-build/static/admin/_next/static/chunks/{5185-bf5655b5d697b714.js → 5185-fc171b6acce9f915.js} +1 -1
  38. fides/ui-build/static/admin/_next/static/chunks/{5258-63325c03319e87dc.js → 5258-cf0d2c4c4d55a94b.js} +1 -1
  39. fides/ui-build/static/admin/_next/static/chunks/{5279-a05b93a8db6a3e79.js → 5279-8637d735471ec7f1.js} +1 -1
  40. fides/ui-build/static/admin/_next/static/chunks/{549-3e3b8d01bc984f96.js → 549-2d9bde37e5fe13eb.js} +1 -1
  41. fides/ui-build/static/admin/_next/static/chunks/{5643-7800464c8df7a78e.js → 5643-48a5e0ad8b9fc3f7.js} +1 -1
  42. fides/ui-build/static/admin/_next/static/chunks/{5783-7deeb7de5d2db4c4.js → 5783-63912bab7f80b0f8.js} +1 -1
  43. fides/ui-build/static/admin/_next/static/chunks/{6277-970bb31d9b0c0007.js → 6277-ec0e3fa4e4614098.js} +1 -1
  44. fides/ui-build/static/admin/_next/static/chunks/6315-79a1506e01f2f92b.js +1 -0
  45. fides/ui-build/static/admin/_next/static/chunks/6419-11d67f7fd4e2f247.js +1 -0
  46. fides/ui-build/static/admin/_next/static/chunks/6853-c348f6e95f987cbf.js +1 -0
  47. fides/ui-build/static/admin/_next/static/chunks/{6954-8b106311a3be35f4.js → 6954-c44ac4e70e777c2f.js} +1 -1
  48. fides/ui-build/static/admin/_next/static/chunks/7059-3f2641e3130b4ef8.js +1 -0
  49. fides/ui-build/static/admin/_next/static/chunks/7245-120f536e09decb85.js +1 -0
  50. fides/ui-build/static/admin/_next/static/chunks/{7476-08717f00da5f89ab.js → 7476-4234fb244676ec13.js} +1 -1
  51. fides/ui-build/static/admin/_next/static/chunks/{7488-bad160a2bfd89871.js → 7488-2db0992474f8056e.js} +1 -1
  52. fides/ui-build/static/admin/_next/static/chunks/{7630-775c578fa8109b0f.js → 7630-d7bd74d0cfdb22df.js} +1 -1
  53. fides/ui-build/static/admin/_next/static/chunks/{7773-24899908bf8ff659.js → 7773-6dce6187fe2c6984.js} +1 -1
  54. fides/ui-build/static/admin/_next/static/chunks/{796-6fe49d134f660156.js → 796-fae64888b8b2f369.js} +1 -1
  55. fides/ui-build/static/admin/_next/static/chunks/{8011-c23d609ed3f0efa5.js → 8011-6e40c969c9fa7d35.js} +1 -1
  56. fides/ui-build/static/admin/_next/static/chunks/{8212-67ac884660ddb63a.js → 8212-18d8da0f9208f978.js} +1 -1
  57. fides/ui-build/static/admin/_next/static/chunks/8373-24379b7d98e6922e.js +1 -0
  58. fides/ui-build/static/admin/_next/static/chunks/9046-6428eac9f38b3886.js +1 -0
  59. fides/ui-build/static/admin/_next/static/chunks/{9330-6eb11127296c54c2.js → 9330-540a113903cb3c28.js} +1 -1
  60. fides/ui-build/static/admin/_next/static/chunks/{9676.1ea49d4b6e0541f2.js → 9676.704cc210f59d0083.js} +1 -1
  61. fides/ui-build/static/admin/_next/static/chunks/9682-a3b2fb1a2df1c948.js +1 -0
  62. fides/ui-build/static/admin/_next/static/chunks/{9826-1f42934a2863992e.js → 9826-aecc5ddec86989dc.js} +1 -1
  63. fides/ui-build/static/admin/_next/static/chunks/{9899-63998972698a49fb.js → 9899-303921e3d0697960.js} +1 -1
  64. fides/ui-build/static/admin/_next/static/chunks/9965-6906ffdaef0f0d69.js +1 -0
  65. fides/ui-build/static/admin/_next/static/chunks/pages/{404-962d132471cd41ba.js → 404-c31cef0ce3fbeebf.js} +1 -1
  66. fides/ui-build/static/admin/_next/static/chunks/pages/{_app-9de54d6135682f7b.js → _app-5fd4e06224960492.js} +11 -11
  67. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/manual-a5865f42aafbe1f8.js +1 -0
  68. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{multiple-e2a5c951347195e3.js → multiple-f706664770dd3e7f.js} +1 -1
  69. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-3f0d8698f01aabc5.js +1 -0
  70. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-7c829e58485fc821.js → add-vendors-fcd031b2b775e4f3.js} +1 -1
  71. fides/ui-build/static/admin/_next/static/chunks/pages/consent/{configure-5c58b69dd473cc06.js → configure-0bd2eb0110873c4d.js} +1 -1
  72. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-58460ac9c1dface5.js → [id]-0dd17c74a6cc17ff.js} +1 -1
  73. fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-experience-b6b2d50d894cefa5.js → privacy-experience-ae8dff75e1c6c413.js} +1 -1
  74. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-25ce8366e689363b.js → [id]-84ba8b9947b9af0a.js} +1 -1
  75. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-faa457089616711a.js → new-f03d1d0df4661a33.js} +1 -1
  76. fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-notices-a7fe3925771bb6c3.js → privacy-notices-5a553b4bdbf85aa9.js} +1 -1
  77. fides/ui-build/static/admin/_next/static/chunks/pages/consent/{properties-45a2901a35edc8f7.js → properties-5cba88e6839a087d.js} +1 -1
  78. fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-f2690c381c1d1a52.js +1 -0
  79. fides/ui-build/static/admin/_next/static/chunks/pages/{consent-a7a4e419e4086033.js → consent-289d21aa6c42828b.js} +1 -1
  80. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/{[projectUrn]-ffb6e0fe6712342e.js → [projectUrn]-cb56d56b9d918682.js} +1 -1
  81. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{projects-3c935e93208d2bdd.js → projects-ccb66ba6d1ad93fc.js} +1 -1
  82. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{resources-96be972a983616e3.js → resources-ecb2d925d75dfe1e.js} +1 -1
  83. fides/ui-build/static/admin/_next/static/chunks/pages/{data-catalog-79d06a04698c47c0.js → data-catalog-75403467491a251b.js} +1 -1
  84. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/datastore/[monitorId]-e46e017a3919f94e.js +1 -0
  85. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/datastore-1b0ed3b3ceedfd94.js +1 -0
  86. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website/[monitorId]/[systemId]-71cf0b06b3d5a326.js +1 -0
  87. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website/[monitorId]-cc6b359fb4968bf0.js +1 -0
  88. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website-60ad14c879b4fe27.js +1 -0
  89. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-cbff5db86e6951c4.js +1 -0
  90. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{activity-6cc1ba1f102ae77d.js → activity-7dded115499a4a4a.js} +1 -1
  91. fides/ui-build/static/admin/_next/static/chunks/pages/datamap-d1bb19fe4ef393dc.js +1 -0
  92. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/{[...subfieldNames]-e04a4e16ccf32aef.js → [...subfieldNames]-58c3f4c0b490264b.js} +1 -1
  93. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/{[collectionName]-a40c4febe16a0a6d.js → [collectionName]-74290432e74fcdc5.js} +1 -1
  94. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{[datasetId]-f500a77eefb057e7.js → [datasetId]-8dad45f070a06609.js} +1 -1
  95. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{new-5c20080cdb053b1d.js → new-6aed6dc24c3be001.js} +1 -1
  96. fides/ui-build/static/admin/_next/static/chunks/pages/{dataset-96355a68e8c28fe8.js → dataset-fdaec997c1b0753f.js} +1 -1
  97. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{[id]-448729ee9d1d78c3.js → [id]-63c4805e40673c60.js} +1 -1
  98. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{new-42c720ec5c941573.js → new-b5a49743387eecef.js} +1 -1
  99. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-8f0804d9a38688a4.js +1 -0
  100. fides/ui-build/static/admin/_next/static/chunks/pages/{index-ca794e85c16cba67.js → index-363b091a4d1d70ad.js} +1 -1
  101. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-3b7f47985452e01d.js +1 -0
  102. fides/ui-build/static/admin/_next/static/chunks/pages/integrations-b0da32fe3564c129.js +1 -0
  103. fides/ui-build/static/admin/_next/static/chunks/pages/new-privacy-requests-d1152cbc3c1bbbbb.js +1 -0
  104. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests/{[id]-058125922d1eaeec.js → [id]-0e4e4e7110362022.js} +1 -1
  105. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests/{new-7a5f76708c79f714.js → new-2e15f6272e9aaeb6.js} +1 -1
  106. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/{digests-31bed1f86b89d1d8.js → digests-65626dfcfacdc605.js} +1 -1
  107. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers/{[key]-d08f3a7cd2d011ec.js → [key]-768c4e2f6b05304c.js} +1 -1
  108. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers/{new-cb2c7fbc26886052.js → new-2d57a70e4d32e651.js} +1 -1
  109. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/{providers-40b9f1f70d27b660.js → providers-83f78354fa34bffe.js} +1 -1
  110. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates/{[id]-a6ae72abe59ff830.js → [id]-1b31764f520fbbc5.js} +1 -1
  111. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates/{add-template-a3e4b5b575b31be1.js → add-template-4c74456b6677bf07.js} +1 -1
  112. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates-5deb80abd6156f7f.js +1 -0
  113. fides/ui-build/static/admin/_next/static/chunks/pages/{notifications-9644c0f088a01fea.js → notifications-8d8716dda9a6f277.js} +1 -1
  114. fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-52b1572442a20ab4.js +1 -0
  115. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/AntForm-a0437ba647d59799.js +1 -0
  116. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikAntFormItem-87285c544450ec46.js +1 -0
  117. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikControlled-57997dbd451a6eed.js +1 -0
  118. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikField-65009783e0404153.js +1 -0
  119. fides/ui-build/static/admin/_next/static/chunks/pages/poc/forms-eafef007c179340f.js +1 -0
  120. fides/ui-build/static/admin/_next/static/chunks/pages/poc/{table-migration-11a70bcfa672ce8f.js → table-migration-7933a824a45d0ee6.js} +1 -1
  121. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-27c56466eab98b15.js +1 -0
  122. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/{storage-24a8c2ab57625556.js → storage-16f77a6291bb02fe.js} +1 -1
  123. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{configure-1926359bdf5d6c30.js → configure-d2b3293ab496f7bc.js} +1 -1
  124. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-af4f48d10926e4a4.js +1 -0
  125. fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-47118b9976ad7212.js → [id]-dd3c3d780533a9c2.js} +1 -1
  126. fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-2e6b0d8b409ba1fd.js → add-property-d1af260c3ddbf68b.js} +1 -1
  127. fides/ui-build/static/admin/_next/static/chunks/pages/{properties-32486c25255c9cb1.js → properties-9bb7fe3577402008.js} +1 -1
  128. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-33ce744d07982c0f.js +1 -0
  129. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-35626e9d8e0a3ca2.js +1 -0
  130. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{consent-4c20c08ca7ea8cff.js → consent-39b5142099ed8705.js} +1 -1
  131. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields/{[id]-a270325109398f48.js → [id]-b5140de4431a7ff5.js} +1 -1
  132. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields/{new-2e0c8e249f286427.js → new-dcc16459e754fbbd.js} +1 -1
  133. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{custom-fields-8e4a76376927afd5.js → custom-fields-64c638ea33bb3ff9.js} +1 -1
  134. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-e3dcef1ec8cf8b9e.js → domain-records-3843fbaf5bc433f1.js} +1 -1
  135. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domains-2e88cc7a6074a28b.js → domains-ea549fabce96fde4.js} +1 -1
  136. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{email-templates-7469d2f85396c693.js → email-templates-0fe318a9dfc1f593.js} +1 -1
  137. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-20789aa0c84d544e.js → locations-c42c856510cad6fd.js} +1 -1
  138. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{organization-f84a13eb9688cb5f.js → organization-e4c552a5797c3fa5.js} +1 -1
  139. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{privacy-requests-b72df6f3d460125f.js → privacy-requests-2790d31b59cc3c74.js} +1 -1
  140. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-aa02bc818e089c49.js → regulations-3c608512c415fca4.js} +1 -1
  141. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/{test-datasets-5be9ce7a745ce908.js → test-datasets-e0e1a5142e41e9f2.js} +1 -1
  142. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-2fc7c0d3988427b3.js → [id]-9e815520adb3e580.js} +1 -1
  143. fides/ui-build/static/admin/_next/static/chunks/pages/systems-d8ce572ad07ed28c.js +1 -0
  144. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-0cae23a599830708.js +1 -0
  145. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/{[id]-6217433a26599521.js → [id]-75d96422db98196f.js} +1 -1
  146. fides/ui-build/static/admin/_next/static/chunks/pages/{user-management-b6c4bf35c003965d.js → user-management-598f98fd88505e1e.js} +1 -1
  147. fides/ui-build/static/admin/_next/static/chunks/{webpack-8eac1ea5c825c8b4.js → webpack-0a3b419ab682b8f9.js} +1 -1
  148. fides/ui-build/static/admin/_next/static/css/012b10627a654d5c.css +1 -0
  149. fides/ui-build/static/admin/_next/static/css/{f38242c11f7fea64.css → 05d05fc31d09638b.css} +1 -1
  150. fides/ui-build/static/admin/_next/static/css/0fd6e0884cfcc5f3.css +1 -0
  151. fides/ui-build/static/admin/_next/static/css/14ba79c49597d37a.css +1 -0
  152. fides/ui-build/static/admin/_next/static/css/{34a7eb08b86ddb57.css → 3d6582469f7d56e0.css} +1 -1
  153. fides/ui-build/static/admin/_next/static/css/4861ca3e088f2d05.css +1 -0
  154. fides/ui-build/static/admin/_next/static/css/{de09ed8a0adf1ca2.css → 919f947a862d28cd.css} +1 -1
  155. fides/ui-build/static/admin/_next/static/css/a1800714b486e230.css +1 -0
  156. fides/ui-build/static/admin/_next/static/css/af32fcac7a177a0e.css +1 -0
  157. fides/ui-build/static/admin/_next/static/css/cb417f0587918f85.css +1 -0
  158. fides/ui-build/static/admin/_next/static/css/dd15c278b964de80.css +1 -0
  159. fides/ui-build/static/admin/_next/static/css/{5f393dea1c0d031c.css → f89607996ad54f4b.css} +1 -1
  160. fides/ui-build/static/admin/_next/static/css/f9a2a44d3d34c904.css +1 -0
  161. fides/ui-build/static/admin/add-systems/manual.html +1 -1
  162. fides/ui-build/static/admin/add-systems/multiple.html +1 -1
  163. fides/ui-build/static/admin/add-systems.html +1 -1
  164. fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
  165. fides/ui-build/static/admin/consent/configure.html +1 -1
  166. fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
  167. fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
  168. fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
  169. fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
  170. fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
  171. fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
  172. fides/ui-build/static/admin/consent/properties.html +1 -1
  173. fides/ui-build/static/admin/consent/reporting.html +1 -1
  174. fides/ui-build/static/admin/consent.html +1 -1
  175. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
  176. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
  177. fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
  178. fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
  179. fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
  180. fides/ui-build/static/admin/data-catalog.html +1 -1
  181. fides/ui-build/static/admin/data-discovery/action-center/datastore/[monitorId].html +1 -0
  182. fides/ui-build/static/admin/data-discovery/action-center/datastore.html +1 -0
  183. fides/ui-build/static/admin/data-discovery/action-center/website/[monitorId]/[systemId].html +1 -0
  184. fides/ui-build/static/admin/data-discovery/action-center/website/[monitorId].html +1 -0
  185. fides/ui-build/static/admin/data-discovery/action-center/website.html +1 -0
  186. fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
  187. fides/ui-build/static/admin/data-discovery/activity.html +1 -1
  188. fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
  189. fides/ui-build/static/admin/data-discovery/detection.html +1 -1
  190. fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
  191. fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
  192. fides/ui-build/static/admin/datamap.html +1 -1
  193. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
  194. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
  195. fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
  196. fides/ui-build/static/admin/dataset/new.html +1 -1
  197. fides/ui-build/static/admin/dataset.html +1 -1
  198. fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
  199. fides/ui-build/static/admin/datastore-connection/new.html +1 -1
  200. fides/ui-build/static/admin/datastore-connection.html +1 -1
  201. fides/ui-build/static/admin/index.html +1 -1
  202. fides/ui-build/static/admin/integrations/[id].html +1 -1
  203. fides/ui-build/static/admin/integrations.html +1 -1
  204. fides/ui-build/static/admin/lib/fides-ext-gpp.js +1 -1
  205. fides/ui-build/static/admin/lib/fides-headless.js +1 -1
  206. fides/ui-build/static/admin/lib/fides-preview.js +1 -1
  207. fides/ui-build/static/admin/lib/fides-tcf.js +3 -3
  208. fides/ui-build/static/admin/lib/fides.js +3 -3
  209. fides/ui-build/static/admin/login/[provider].html +1 -1
  210. fides/ui-build/static/admin/login.html +1 -1
  211. fides/ui-build/static/admin/new-privacy-requests.html +1 -0
  212. fides/ui-build/static/admin/notifications/digests/[id].html +1 -1
  213. fides/ui-build/static/admin/notifications/digests/new.html +1 -1
  214. fides/ui-build/static/admin/notifications/digests.html +1 -1
  215. fides/ui-build/static/admin/notifications/providers/[key].html +1 -1
  216. fides/ui-build/static/admin/notifications/providers/new.html +1 -1
  217. fides/ui-build/static/admin/notifications/providers.html +1 -1
  218. fides/ui-build/static/admin/notifications/templates/[id].html +1 -1
  219. fides/ui-build/static/admin/notifications/templates/add-template.html +1 -1
  220. fides/ui-build/static/admin/notifications/templates.html +1 -1
  221. fides/ui-build/static/admin/notifications.html +1 -1
  222. fides/ui-build/static/admin/poc/ant-components.html +1 -1
  223. fides/ui-build/static/admin/poc/form-experiments/AntForm.html +1 -1
  224. fides/ui-build/static/admin/poc/form-experiments/FormikAntFormItem.html +1 -1
  225. fides/ui-build/static/admin/poc/form-experiments/FormikControlled.html +1 -1
  226. fides/ui-build/static/admin/poc/form-experiments/FormikField.html +1 -1
  227. fides/ui-build/static/admin/poc/form-experiments/FormikSpreadField.html +1 -1
  228. fides/ui-build/static/admin/poc/forms.html +1 -1
  229. fides/ui-build/static/admin/poc/table-migration.html +1 -1
  230. fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
  231. fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
  232. fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
  233. fides/ui-build/static/admin/privacy-requests.html +1 -1
  234. fides/ui-build/static/admin/properties/[id].html +1 -1
  235. fides/ui-build/static/admin/properties/add-property.html +1 -1
  236. fides/ui-build/static/admin/properties.html +1 -1
  237. fides/ui-build/static/admin/reporting/datamap.html +1 -1
  238. fides/ui-build/static/admin/settings/about/alpha.html +1 -1
  239. fides/ui-build/static/admin/settings/about.html +1 -1
  240. fides/ui-build/static/admin/settings/consent/[configuration_id]/[purpose_id].html +1 -1
  241. fides/ui-build/static/admin/settings/consent.html +1 -1
  242. fides/ui-build/static/admin/settings/custom-fields/[id].html +1 -1
  243. fides/ui-build/static/admin/settings/custom-fields/new.html +1 -1
  244. fides/ui-build/static/admin/settings/custom-fields.html +1 -1
  245. fides/ui-build/static/admin/settings/domain-records.html +1 -1
  246. fides/ui-build/static/admin/settings/domains.html +1 -1
  247. fides/ui-build/static/admin/settings/email-templates.html +1 -1
  248. fides/ui-build/static/admin/settings/locations.html +1 -1
  249. fides/ui-build/static/admin/settings/organization.html +1 -1
  250. fides/ui-build/static/admin/settings/privacy-requests.html +1 -1
  251. fides/ui-build/static/admin/settings/regulations.html +1 -1
  252. fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
  253. fides/ui-build/static/admin/systems/configure/[id].html +1 -1
  254. fides/ui-build/static/admin/systems.html +1 -1
  255. fides/ui-build/static/admin/taxonomy.html +1 -1
  256. fides/ui-build/static/admin/user-management/new.html +1 -1
  257. fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
  258. fides/ui-build/static/admin/user-management.html +1 -1
  259. fides/ui-build/static/admin/_next/static/chunks/155-bf4e3ffb18f29226.js +0 -1
  260. fides/ui-build/static/admin/_next/static/chunks/1896-49010da5c2705fc5.js +0 -1
  261. fides/ui-build/static/admin/_next/static/chunks/2150-930ffaf2c4718edc.js +0 -1
  262. fides/ui-build/static/admin/_next/static/chunks/255-1bc0cbef7a59cdc6.js +0 -1
  263. fides/ui-build/static/admin/_next/static/chunks/2921-9b596ba7f5267afc.js +0 -1
  264. fides/ui-build/static/admin/_next/static/chunks/2962-e92d525bf570a9a3.js +0 -1
  265. fides/ui-build/static/admin/_next/static/chunks/3550-83cb70e80cbe41ba.js +0 -1
  266. fides/ui-build/static/admin/_next/static/chunks/4817-066598cef25d7e88.js +0 -1
  267. fides/ui-build/static/admin/_next/static/chunks/6315-4a2151f87c7eefb6.js +0 -1
  268. fides/ui-build/static/admin/_next/static/chunks/6419-9b3a86af57c86791.js +0 -1
  269. fides/ui-build/static/admin/_next/static/chunks/6853-6d64d627df6f8194.js +0 -1
  270. fides/ui-build/static/admin/_next/static/chunks/7245-53a20677c49b41c8.js +0 -1
  271. fides/ui-build/static/admin/_next/static/chunks/8373-43b6df89a2085d6b.js +0 -1
  272. fides/ui-build/static/admin/_next/static/chunks/9046-3a08a09a598396ca.js +0 -1
  273. fides/ui-build/static/admin/_next/static/chunks/9070-6d3aaaf5aa5913ba.js +0 -1
  274. fides/ui-build/static/admin/_next/static/chunks/9682-65d253d54f84f6f2.js +0 -1
  275. fides/ui-build/static/admin/_next/static/chunks/9965-4709f43bf62af9a9.js +0 -1
  276. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/manual-055d058d16c02957.js +0 -1
  277. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-0058fe05f2d23d1a.js +0 -1
  278. fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-e9ec351281c54822.js +0 -1
  279. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-e50e9c8e11412b2a.js +0 -1
  280. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/data-explorer-09a3a992e564f971.js +0 -1
  281. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-878aa4ab0746df5b.js +0 -1
  282. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-a2e9c0bfa67c633d.js +0 -1
  283. fides/ui-build/static/admin/_next/static/chunks/pages/datamap-18f255a8bbeecaa4.js +0 -1
  284. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-a8fc95a46de38b35.js +0 -1
  285. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-2f1dc17eba11fb4e.js +0 -1
  286. fides/ui-build/static/admin/_next/static/chunks/pages/integrations-bbec0140433a199b.js +0 -1
  287. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates-4918f86f7300ac9b.js +0 -1
  288. fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-39b5586d9c8b64aa.js +0 -1
  289. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/AntForm-5163f3213377bd35.js +0 -1
  290. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikAntFormItem-0b1547cd9b114c6b.js +0 -1
  291. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikControlled-da562cba4cffd6bb.js +0 -1
  292. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikField-3a587676869d2ef6.js +0 -1
  293. fides/ui-build/static/admin/_next/static/chunks/pages/poc/forms-defc3b917306a6d8.js +0 -1
  294. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-787621468b5a7619.js +0 -1
  295. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-da634187d8201ab3.js +0 -1
  296. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-e410d13a2b35cff4.js +0 -1
  297. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-aec1bf8a409ec75f.js +0 -1
  298. fides/ui-build/static/admin/_next/static/chunks/pages/systems-86f5557384124f79.js +0 -1
  299. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-2589729c47976357.js +0 -1
  300. fides/ui-build/static/admin/_next/static/css/23cf870196941c9a.css +0 -1
  301. fides/ui-build/static/admin/_next/static/css/304c6f148886a8d4.css +0 -1
  302. fides/ui-build/static/admin/_next/static/hRLR7azkI57zC2PfdYodO/_buildManifest.js +0 -1
  303. fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/[systemId].html +0 -1
  304. fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/data-explorer.html +0 -1
  305. fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +0 -1
  306. {ethyca_fides-2.72.3rc1.dist-info → ethyca_fides-2.73.0.dist-info}/WHEEL +0 -0
  307. {ethyca_fides-2.72.3rc1.dist-info → ethyca_fides-2.73.0.dist-info}/entry_points.txt +0 -0
  308. {ethyca_fides-2.72.3rc1.dist-info → ethyca_fides-2.73.0.dist-info}/licenses/LICENSE +0 -0
  309. {ethyca_fides-2.72.3rc1.dist-info → ethyca_fides-2.73.0.dist-info}/top_level.txt +0 -0
  310. /fides/ui-build/static/admin/_next/static/{hRLR7azkI57zC2PfdYodO → 6kEWO-NXzxn1tvUedYFei}/_ssgManifest.js +0 -0
  311. /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/{[resourceUrn]-3b59925f6c9a13a9.js → [resourceUrn]-5d133ec635cd716c.js} +0 -0
  312. /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/{[resourceUrn]-8d7d9152e215c3b6.js → [resourceUrn]-9d8efe43b69a285d.js} +0 -0
  313. /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-260f5deb68966b70.js → [resourceUrn]-2df143c1e1f79040.js} +0 -0
  314. /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-d735dab3d9f3adc5.js → detection-e37c800313e2a422.js} +0 -0
  315. /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-c7f055275a2c503f.js → [resourceUrn]-7022ca5fa834b633.js} +0 -0
  316. /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-b1cfd55c7e127865.js → discovery-6178e22397f20f92.js} +0 -0
  317. /fides/ui-build/static/admin/_next/static/chunks/pages/user-management/{new-e399005c3bb4db1b.js → new-bc1568bb47d198a9.js} +0 -0
fides/_version.py CHANGED
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2025-10-21T10:52:42-0300",
11
+ "date": "2025-10-24T16:42:20-0700",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "9a96fc10ec86ded899e833ed49eabea81a1b04a2",
15
- "version": "2.72.3rc1"
14
+ "full-revisionid": "ca872f4fade7f59c7c49c558ecb610e1f0b41128",
15
+ "version": "2.73.0"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -0,0 +1,29 @@
1
+ """add_tagging_instructions_to_data_category
2
+
3
+ Revision ID: a55e12c2c2df
4
+ Revises: 65a1bc82ae09
5
+ Create Date: 2025-10-13 21:14:00.723464
6
+
7
+ """
8
+
9
+ import sqlalchemy as sa
10
+ from alembic import op
11
+
12
+ # revision identifiers, used by Alembic.
13
+ revision = "a55e12c2c2df"
14
+ down_revision = "65a1bc82ae09"
15
+ branch_labels = None
16
+ depends_on = None
17
+
18
+
19
+ def upgrade():
20
+ """Add tagging_instructions column to ctl_data_categories table."""
21
+ op.add_column(
22
+ "ctl_data_categories",
23
+ sa.Column("tagging_instructions", sa.Text(), nullable=True),
24
+ )
25
+
26
+
27
+ def downgrade():
28
+ """Remove tagging_instructions column from ctl_data_categories table."""
29
+ op.drop_column("ctl_data_categories", "tagging_instructions")
@@ -1,7 +1,7 @@
1
1
  from functools import partial
2
2
  from typing import Dict, List, Optional, Union
3
3
 
4
- from fastapi import Depends, HTTPException, Query, Response, Security
4
+ from fastapi import Body, Depends, HTTPException, Query, Response, Security
5
5
  from fastapi.concurrency import run_in_threadpool
6
6
  from fastapi.encoders import jsonable_encoder
7
7
  from fastapi.responses import JSONResponse
@@ -516,6 +516,75 @@ async def update_data_category(
516
516
  )
517
517
 
518
518
 
519
+ @data_category_router.patch(
520
+ "/data_category/{fides_key}/tagging_instructions",
521
+ dependencies=[Security(verify_oauth_client, scopes=[DATA_CATEGORY_UPDATE])],
522
+ response_model=DataCategory,
523
+ status_code=status.HTTP_200_OK,
524
+ name="Update tagging instructions",
525
+ )
526
+ async def update_data_category_tagging_instructions(
527
+ fides_key: str,
528
+ tagging_instructions: str = Body(..., embed=True),
529
+ taxonomy_service: TaxonomyService = Depends(get_taxonomy_service),
530
+ ) -> Dict:
531
+ """
532
+ Update or add tagging_instructions for a data category.
533
+ This is used by LLM-based classification to provide custom instructions for tagging.
534
+ """
535
+ try:
536
+ result = taxonomy_service.update_element(
537
+ "data_categories",
538
+ fides_key,
539
+ {"tagging_instructions": tagging_instructions},
540
+ )
541
+ if not result:
542
+ raise HTTPException(
543
+ status_code=HTTP_404_NOT_FOUND,
544
+ detail=f"Data category not found with key: {fides_key}",
545
+ )
546
+ return result
547
+ except (ValidationError, PydanticValidationError) as e:
548
+ raise HTTPException(
549
+ status_code=HTTP_422_UNPROCESSABLE_ENTITY,
550
+ detail=str(e),
551
+ )
552
+
553
+
554
+ @data_category_router.delete(
555
+ "/data_category/{fides_key}/tagging_instructions",
556
+ dependencies=[Security(verify_oauth_client, scopes=[DATA_CATEGORY_UPDATE])],
557
+ response_model=DataCategory,
558
+ status_code=status.HTTP_200_OK,
559
+ name="Delete tagging instructions",
560
+ )
561
+ async def delete_data_category_tagging_instructions(
562
+ fides_key: str,
563
+ taxonomy_service: TaxonomyService = Depends(get_taxonomy_service),
564
+ ) -> Dict:
565
+ """
566
+ Remove tagging_instructions from a data category.
567
+ Sets the tagging_instructions field to None.
568
+ """
569
+ try:
570
+ result = taxonomy_service.update_element(
571
+ "data_categories",
572
+ fides_key,
573
+ {"tagging_instructions": None},
574
+ )
575
+ if not result:
576
+ raise HTTPException(
577
+ status_code=HTTP_404_NOT_FOUND,
578
+ detail=f"Data category not found with key: {fides_key}",
579
+ )
580
+ return result
581
+ except (ValidationError, PydanticValidationError) as e:
582
+ raise HTTPException(
583
+ status_code=HTTP_422_UNPROCESSABLE_ENTITY,
584
+ detail=str(e),
585
+ )
586
+
587
+
519
588
  GENERIC_OVERRIDES_ROUTER = APIRouter()
520
589
  GENERIC_OVERRIDES_ROUTER.include_router(dataset_router)
521
590
  GENERIC_OVERRIDES_ROUTER.include_router(data_use_router)
@@ -58,6 +58,7 @@ class ConsentMethod(Enum):
58
58
  gpc = "gpc"
59
59
  individual_notice = "individual_notice"
60
60
  acknowledge = "acknowledge"
61
+ external_provider = "external_provider"
61
62
 
62
63
 
63
64
  class ServingComponent(Enum):
@@ -184,6 +184,9 @@ class DataCategory(Base, FidesBase):
184
184
  version_deprecated = Column(Text)
185
185
  replaced_by = Column(Text)
186
186
 
187
+ # LLM Classification
188
+ tagging_instructions = Column(Text, nullable=True)
189
+
187
190
  children: "RelationshipProperty[List[DataCategory]]" = relationship(
188
191
  "DataCategory",
189
192
  back_populates="parent",
@@ -23,6 +23,10 @@ class DataUse(BaseDataUse):
23
23
 
24
24
  class DataCategory(BaseDataCategory):
25
25
  active: bool = active_field
26
+ tagging_instructions: Optional[str] = Field(
27
+ default=None,
28
+ description="Instructions for LLM-based data classification tagging.",
29
+ )
26
30
 
27
31
 
28
32
  class DataSubject(BaseDataSubject):
@@ -44,6 +48,10 @@ class DataUseCreateOrUpdate(TaxonomyCreateOrUpdateBase):
44
48
 
45
49
  class DataCategoryCreateOrUpdate(TaxonomyCreateOrUpdateBase):
46
50
  parent_key: Optional[FidesKey] = None
51
+ tagging_instructions: Optional[str] = Field(
52
+ default=None,
53
+ description="Instructions for LLM-based data classification tagging.",
54
+ )
47
55
 
48
56
 
49
57
  class DataSubjectCreateOrUpdate(TaxonomyCreateOrUpdateBase):
@@ -157,6 +157,7 @@ class AsyncPollingStrategy(AsyncDSRStrategy):
157
157
  logger.info(
158
158
  f"Creating initial polling sub-requests for task {request_task.id}"
159
159
  )
160
+
160
161
  self._handle_polling_initial_request(
161
162
  request_task,
162
163
  query_config,
@@ -83,12 +83,10 @@ class SaaSQueryConfig(QueryConfig[SaaSRequestParams]):
83
83
  """
84
84
  Returns the appropriate request configs based on the current collection and identity
85
85
  """
86
- collection_name = self.node.address.collection
87
-
88
86
  try:
89
- requests = self.endpoints[collection_name].requests
87
+ requests = self.endpoints[self.collection_name].requests
90
88
  except KeyError:
91
- logger.error("The '{}' endpoint is not defined", collection_name)
89
+ logger.error("The '{}' endpoint is not defined", self.collection_name)
92
90
  return []
93
91
 
94
92
  if not requests.read:
@@ -282,6 +280,111 @@ class SaaSQueryConfig(QueryConfig[SaaSRequestParams]):
282
280
  name: value for name, value in self.secrets.items() if name in param_names
283
281
  }
284
282
 
283
+ def _safe_extract_value(self, value_list: Optional[List[Any]]) -> Optional[Any]:
284
+ """
285
+ Safely extract the first value from a list
286
+ """
287
+ return value_list[0] if value_list else None
288
+
289
+ def _process_param_values_for_query(
290
+ self,
291
+ request: SaaSRequest,
292
+ input_data: Dict[str, List[Any]],
293
+ param_values: Dict[str, Any],
294
+ ) -> None:
295
+ """
296
+ Process param_values for query generation on access requests.
297
+ """
298
+ for param_value in request.param_values or []:
299
+ if param_value.references or param_value.identity:
300
+ input_list = input_data.get(param_value.name)
301
+ if input_list:
302
+ param_values[param_value.name] = self._safe_extract_value(
303
+ input_list
304
+ )
305
+ elif param_value.connector_param:
306
+ connector_value = pydash.get(input_data, param_value.connector_param)
307
+ param_values[param_value.name] = self._safe_extract_value(
308
+ connector_value
309
+ )
310
+
311
+ def _process_param_values_for_update(
312
+ self,
313
+ request: SaaSRequest,
314
+ collection_values: Dict[str, Row],
315
+ identity_data: Dict[str, Any],
316
+ input_data: Optional[Dict[str, List[Any]]] = None,
317
+ param_values: Dict[str, Any] = {},
318
+ ) -> None:
319
+ """
320
+ Process param_values for update generation (erasure requests).
321
+ Modifies param_values in place.
322
+
323
+ Args:
324
+ request: The SaaS request configuration
325
+ collection_values: Collection data for reference resolution
326
+ identity_data: Identity data for parameter resolution
327
+ input_data: Optional upstream data from other collections
328
+ """
329
+ for param_value in request.param_values or []:
330
+ if param_value.references:
331
+ # we resolve the param reference here for consistency,
332
+ # i.e. as if it may be a pointer to an `external_reference`.
333
+ # Cross-collection references are now supported by looking up data
334
+ # from upstream collections passed via input_data.
335
+ reference: FidesDatasetReference = SaaSConfig.resolve_param_reference(
336
+ param_value.references[0], self.secrets
337
+ )
338
+ param_values[param_value.name] = pydash.get(
339
+ collection_values, reference.field
340
+ )
341
+ if param_values[param_value.name] is None and input_data:
342
+ logger.info(
343
+ "Reference not found in collection, checking input data from upstream tasks"
344
+ )
345
+ # If the reference is not found in the collection (None), check the input data from upstream tasks
346
+ input_list = input_data.get(param_value.name)
347
+ if input_list:
348
+ param_values[param_value.name] = self._safe_extract_value(
349
+ input_list
350
+ )
351
+
352
+ elif param_value.identity:
353
+ param_values[param_value.name] = pydash.get(
354
+ identity_data, param_value.identity
355
+ )
356
+ elif param_value.connector_param:
357
+ param_values[param_value.name] = pydash.get(
358
+ self.secrets, param_value.connector_param
359
+ )
360
+
361
+ def _add_standard_parameters(
362
+ self,
363
+ param_values: Dict[str, Any],
364
+ ) -> None:
365
+ """
366
+ Add standard parameters that are common across query and update operations.
367
+ """
368
+
369
+ # common parameters for read and update
370
+ if self.privacy_request:
371
+ param_values[PRIVACY_REQUEST_ID] = self.privacy_request.id
372
+ param_values[UUID] = str(uuid4())
373
+ param_values[ISO_8601_DATETIME] = datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")
374
+ param_values[FIELD_LIST] = ",".join(
375
+ [
376
+ field.name
377
+ for field in self.top_level_field_map().values()
378
+ if field.data_type() != "None"
379
+ ]
380
+ )
381
+
382
+ if self.request_task and self.request_task.id:
383
+ param_values[REPLY_TO_TOKEN] = generate_request_task_callback_jwe(
384
+ self.request_task
385
+ )
386
+ param_values[REPLY_TO] = V1_URL_PREFIX + REQUEST_TASK_CALLBACK
387
+
285
388
  @staticmethod
286
389
  def _generate_product_list(*args: Dict[str, Any]) -> List[Dict[str, Any]]:
287
390
  """
@@ -331,22 +434,11 @@ class SaaSQueryConfig(QueryConfig[SaaSRequestParams]):
331
434
  f"The 'read' action is not defined for the '{self.collection_name}' "
332
435
  f"endpoint in {self.node.connection_key}"
333
436
  )
334
-
335
- # create the source of param values to populate the various placeholders
336
- # in the path, headers, query_params, and body
337
437
  param_values: Dict[str, Any] = {}
338
- for param_value in self.current_request.param_values or []:
339
- if param_value.references or param_value.identity:
340
- input_list = input_data.get(param_value.name)
341
- if input_list:
342
- param_values[param_value.name] = input_list[0]
343
- elif param_value.connector_param:
344
- param_values[param_value.name] = pydash.get(
345
- input_data, param_value.connector_param
346
- )[0]
347
-
348
- if self.privacy_request:
349
- param_values[PRIVACY_REQUEST_ID] = self.privacy_request.id
438
+ # Process param values using utility method
439
+ self._process_param_values_for_query(
440
+ self.current_request, input_data, param_values
441
+ )
350
442
 
351
443
  privacy_request_object = input_data.get(PRIVACY_REQUEST_OBJECT)
352
444
  if (
@@ -365,21 +457,9 @@ class SaaSQueryConfig(QueryConfig[SaaSRequestParams]):
365
457
  0
366
458
  ]
367
459
 
368
- param_values[UUID] = str(uuid4())
369
- # Use full ISO-8601 timestamp including time component (UTC, seconds precision)
370
- param_values[ISO_8601_DATETIME] = datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")
371
- param_values[FIELD_LIST] = ",".join(
372
- [
373
- field.name
374
- for field in self.top_level_field_map().values()
375
- if field.data_type() != "None"
376
- ]
377
- )
378
- if self.request_task and self.request_task.id:
379
- param_values[REPLY_TO_TOKEN] = generate_request_task_callback_jwe(
380
- self.request_task
381
- )
382
- param_values[REPLY_TO] = V1_URL_PREFIX + REQUEST_TASK_CALLBACK
460
+ # Add standard parameters
461
+ # For generate_query, we don't have a PrivacyRequest object, so we use self.privacy_request
462
+ self._add_standard_parameters(param_values)
383
463
 
384
464
  # map param values to placeholders in path, headers, and query params
385
465
  saas_request_params: SaaSRequestParams = saas_util.map_param_values(
@@ -391,16 +471,26 @@ class SaaSQueryConfig(QueryConfig[SaaSRequestParams]):
391
471
  return saas_request_params
392
472
 
393
473
  def generate_update_stmt(
394
- self, row: Row, policy: Policy, request: PrivacyRequest
474
+ self,
475
+ row: Row,
476
+ policy: Policy,
477
+ request: PrivacyRequest,
478
+ input_data: Optional[Dict[str, List[Any]]] = None,
395
479
  ) -> SaaSRequestParams:
396
480
  """
397
481
  This returns the method, path, header, query, and body params needed to make an API call.
398
482
  The fields in the row are masked according to the policy and added to the request body
399
483
  if specified by the body field of the masking request.
484
+
485
+ Args:
486
+ row: The current row data from this collection
487
+ policy: The privacy policy being applied
488
+ request: The privacy request being processed
489
+ input_data: Optional upstream data from other collections for cross-collection references
400
490
  """
401
491
  current_request: SaaSRequest = self.get_masking_request() # type: ignore
402
492
  param_values: Dict[str, Any] = self.generate_update_param_values(
403
- row, policy, request, current_request
493
+ row, policy, request, current_request, input_data
404
494
  )
405
495
 
406
496
  return self.generate_update_request_params(param_values, current_request)
@@ -429,6 +519,7 @@ class SaaSQueryConfig(QueryConfig[SaaSRequestParams]):
429
519
  policy: Policy,
430
520
  privacy_request: PrivacyRequest,
431
521
  saas_request: SaaSRequest,
522
+ input_data: Optional[Dict[str, List[Any]]] = None,
432
523
  ) -> Dict[str, Any]:
433
524
  """
434
525
  A utility that generates the update request param values
@@ -439,10 +530,16 @@ class SaaSQueryConfig(QueryConfig[SaaSRequestParams]):
439
530
  the fields in the provided row that have been masked according
440
531
  to provided policy. The `all_object_fields` key maps to a JSON structure
441
532
  that holds all values, including those that have not been masked.
533
+
534
+ Args:
535
+ row: The current row data from this collection
536
+ policy: The privacy policy being applied
537
+ privacy_request: The privacy request being processed
538
+ saas_request: The SaaS request configuration
539
+ input_data: Optional upstream data from other collections for cross-collection references
442
540
  """
443
541
 
444
- collection_name: str = self.node.address.collection
445
- collection_values: Dict[str, Row] = {collection_name: row}
542
+ collection_values: Dict[str, Row] = {self.collection_name: row}
446
543
  identity_data: Dict[str, Any] = privacy_request.get_cached_identity_data()
447
544
  custom_privacy_request_fields: Dict[str, Any] = (
448
545
  privacy_request.get_cached_custom_privacy_request_fields()
@@ -451,48 +548,15 @@ class SaaSQueryConfig(QueryConfig[SaaSRequestParams]):
451
548
  # create the source of param values to populate the various placeholders
452
549
  # in the path, headers, query_params, and body
453
550
  param_values: Dict[str, Any] = {}
454
- for param_value in saas_request.param_values or []:
455
- if param_value.references:
456
- # we resolve the param reference here for consistency,
457
- # i.e. as if it may be a pointer to an `external_reference`.
458
- # however, `references` in update requests can, currently, only reference
459
- # the same collection the same collection, and so it is highly unlikely
460
- # that this would be an external reference at this point.
461
- reference: FidesDatasetReference = SaaSConfig.resolve_param_reference(
462
- param_value.references[0], self.secrets
463
- )
464
- param_values[param_value.name] = pydash.get(
465
- collection_values, reference.field
466
- )
467
- elif param_value.identity:
468
- param_values[param_value.name] = pydash.get(
469
- identity_data, param_value.identity
470
- )
471
- elif param_value.connector_param:
472
- param_values[param_value.name] = pydash.get(
473
- self.secrets, param_value.connector_param
474
- )
475
-
476
- if self.privacy_request:
477
- param_values[PRIVACY_REQUEST_ID] = self.privacy_request.id
551
+ # Process param values using utility method
552
+ self._process_param_values_for_update(
553
+ saas_request, collection_values, identity_data, input_data, param_values
554
+ )
478
555
 
479
556
  param_values[PRIVACY_REQUEST_OBJECT] = privacy_request.to_safe_dict()
480
-
481
557
  param_values[CUSTOM_PRIVACY_REQUEST_FIELDS] = custom_privacy_request_fields
482
- param_values[UUID] = str(uuid4())
483
- param_values[ISO_8601_DATETIME] = datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")
484
- param_values[FIELD_LIST] = ",".join(
485
- [
486
- field.name
487
- for field in self.top_level_field_map().values()
488
- if field.data_type() != "None"
489
- ]
490
- )
491
- if self.request_task and self.request_task.id:
492
- param_values[REPLY_TO_TOKEN] = generate_request_task_callback_jwe(
493
- self.request_task
494
- )
495
- param_values[REPLY_TO] = V1_URL_PREFIX + REQUEST_TASK_CALLBACK
558
+ # Add standard parameters
559
+ self._add_standard_parameters(param_values)
496
560
  # remove any row values for fields marked as read-only, these will be omitted from all update maps
497
561
  for field_path, field in self.field_map().items():
498
562
  if field.read_only:
@@ -518,7 +582,6 @@ class SaaSQueryConfig(QueryConfig[SaaSRequestParams]):
518
582
 
519
583
  param_values[MASKED_OBJECT_FIELDS] = masked_object
520
584
  param_values[ALL_OBJECT_FIELDS] = complete_object
521
-
522
585
  return param_values
523
586
 
524
587
  def generate_update_request_params(
@@ -71,6 +71,7 @@ from fides.api.util.saas_util import (
71
71
  CUSTOM_PRIVACY_REQUEST_FIELDS,
72
72
  PRIVACY_REQUEST_OBJECT,
73
73
  assign_placeholders,
74
+ check_dataset_missing_reference_values,
74
75
  map_param_values,
75
76
  )
76
77
 
@@ -229,21 +230,8 @@ class SaaSConnector(BaseConnector[AuthenticatedClient], Contextualizable):
229
230
 
230
231
  # pylint: disable=too-many-branches
231
232
  self.set_privacy_request_state(privacy_request, node, request_task)
232
-
233
233
  query_config: SaaSQueryConfig = self.query_config(node)
234
234
 
235
- # Delegate async requests
236
- with get_db() as db:
237
- if async_dsr_strategy := _get_async_dsr_strategy(
238
- db, request_task, query_config, ActionType.access
239
- ):
240
- return async_dsr_strategy.async_retrieve_data(
241
- client=self.create_client(),
242
- request_task_id=request_task.id,
243
- query_config=query_config,
244
- input_data=input_data,
245
- )
246
-
247
235
  # generate initial set of requests if read request is defined, otherwise raise an exception
248
236
  # An endpoint can be defined with multiple 'read' requests if the data for a single
249
237
  # collection can be accessed in multiple ways for example:
@@ -280,16 +268,31 @@ class SaaSConnector(BaseConnector[AuthenticatedClient], Contextualizable):
280
268
  input_data[CUSTOM_PRIVACY_REQUEST_FIELDS] = [custom_privacy_request_fields]
281
269
 
282
270
  input_data[PRIVACY_REQUEST_OBJECT] = [privacy_request.to_safe_dict()]
283
-
284
- rows: List[Row] = []
271
+ # check all the values specified by param_values are provided in input_data
285
272
  for read_request in read_requests:
286
- self.set_saas_request_state(read_request)
287
- # check all the values specified by param_values are provided in input_data
288
273
  if self._missing_dataset_reference_values(
289
274
  input_data, read_request.param_values
290
275
  ):
291
276
  return []
292
277
 
278
+ # Delegate async requests
279
+ with get_db() as db:
280
+ # Guard clause to ensure we only run async access requests for access requests
281
+ if self.guard_access_request(policy):
282
+ if async_dsr_strategy := _get_async_dsr_strategy(
283
+ db, request_task, query_config, ActionType.access
284
+ ):
285
+ return async_dsr_strategy.async_retrieve_data(
286
+ client=self.create_client(),
287
+ request_task_id=request_task.id,
288
+ query_config=query_config,
289
+ input_data=input_data,
290
+ )
291
+
292
+ rows: List[Row] = []
293
+ for read_request in read_requests:
294
+ self.set_saas_request_state(read_request)
295
+
293
296
  # hook for user-provided request override functions
294
297
  if read_request.request_override:
295
298
  return self._invoke_read_request_override(
@@ -347,6 +350,19 @@ class SaaSConnector(BaseConnector[AuthenticatedClient], Contextualizable):
347
350
  self.unset_connector_state()
348
351
  return rows
349
352
 
353
+ def guard_access_request(self, policy: Policy) -> bool:
354
+ """
355
+ Guard clause to ensure we only run async access requests
356
+ if the access request is enabled and we are in an Access Request
357
+ """
358
+ if (
359
+ self.configuration.enabled_actions is None
360
+ or ActionType.access in self.configuration.enabled_actions
361
+ ):
362
+ if policy.get_rules_for_action(ActionType.access):
363
+ return True
364
+ return False
365
+
350
366
  def _apply_output_template(
351
367
  self,
352
368
  param_value_maps: List[Dict[str, Any]],
@@ -376,29 +392,15 @@ class SaaSConnector(BaseConnector[AuthenticatedClient], Contextualizable):
376
392
  return result
377
393
 
378
394
  def _missing_dataset_reference_values(
379
- self, input_data: Dict[str, Any], param_values: Optional[List[ParamValue]]
395
+ self, input_data: Dict[str, List[Any]], param_values: Optional[List[ParamValue]]
380
396
  ) -> List[str]:
381
397
  """Return a list of dataset reference values that are not found in the input_data map"""
382
-
383
- # get the list of param_value references
384
- required_param_value_references = [
385
- param_value.name
386
- for param_value in param_values or []
387
- if param_value.references
388
- ]
389
-
390
- # extract the keys from inside the fides_grouped_inputs and append them the other input_data keys
391
- provided_input_keys = (
392
- list(input_data.get("fidesops_grouped_inputs")[0].keys()) # type: ignore
393
- if input_data.get("fidesops_grouped_inputs")
394
- else []
395
- ) + list(input_data.keys())
396
-
397
- # find the missing values
398
- missing_dataset_reference_values = list(
399
- set(required_param_value_references) - set(provided_input_keys)
398
+ missing_dataset_reference_values = check_dataset_missing_reference_values(
399
+ input_data, param_values
400
+ )
401
+ logger.info(
402
+ f"Missing dataset reference values: {missing_dataset_reference_values}"
400
403
  )
401
-
402
404
  if missing_dataset_reference_values:
403
405
  logger.info(
404
406
  "The '{}' request of {} is missing the following dataset reference values [{}], skipping traversal",
@@ -545,7 +547,6 @@ class SaaSConnector(BaseConnector[AuthenticatedClient], Contextualizable):
545
547
  query_config=query_config,
546
548
  rows=rows,
547
549
  )
548
-
549
550
  masking_request = query_config.get_masking_request()
550
551
  rows_updated = 0
551
552
 
@@ -591,7 +592,7 @@ class SaaSConnector(BaseConnector[AuthenticatedClient], Contextualizable):
591
592
  for row in rows:
592
593
  try:
593
594
  prepared_request = query_config.generate_update_stmt(
594
- row, policy, privacy_request
595
+ row, policy, privacy_request, input_data
595
596
  )
596
597
  except ValueError as exc:
597
598
  if masking_request.skip_missing_param_values:
@@ -786,10 +787,11 @@ class SaaSConnector(BaseConnector[AuthenticatedClient], Contextualizable):
786
787
 
787
788
  else:
788
789
  # follow the basic (global opt-in/out) SaaS consent flow
789
- should_opt_in, filtered_preferences = (
790
- build_user_consent_and_filtered_preferences_for_service(
791
- self.configuration.system, privacy_request, session, False
792
- )
790
+ (
791
+ should_opt_in,
792
+ filtered_preferences,
793
+ ) = build_user_consent_and_filtered_preferences_for_service(
794
+ self.configuration.system, privacy_request, session, False
793
795
  )
794
796
 
795
797
  if should_opt_in is None:
@@ -320,7 +320,7 @@ def initiate_polling_task_requeue() -> None:
320
320
  id=ASYNC_TASKS_STATUS_POLLING,
321
321
  coalesce=True,
322
322
  replace_existing=True,
323
- seconds=20,
323
+ seconds=CONFIG.execution.async_polling_interval_hours * 3600,
324
324
  )
325
325
 
326
326