ethyca-fides 2.66.2rc0__py2.py3-none-any.whl → 2.66.3b0__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 (282) hide show
  1. {ethyca_fides-2.66.2rc0.dist-info → ethyca_fides-2.66.3b0.dist-info}/METADATA +1 -1
  2. {ethyca_fides-2.66.2rc0.dist-info → ethyca_fides-2.66.3b0.dist-info}/RECORD +270 -259
  3. fides/_version.py +3 -3
  4. fides/api/alembic/migrations/versions/7e9a2b52f498_adding_masking_secrets.py +60 -0
  5. fides/api/alembic/migrations/versions/a7065df4dcf1_add_finalized_fields_to_privacy_request.py +65 -0
  6. fides/api/alembic/migrations/versions/d0031087eacb_create_manualtaskconditionaldependency_.py +106 -0
  7. fides/api/api/v1/endpoints/dataset_config_endpoints.py +13 -5
  8. fides/api/api/v1/endpoints/drp_endpoints.py +7 -1
  9. fides/api/api/v1/endpoints/privacy_request_endpoints.py +44 -1
  10. fides/api/api/v1/endpoints/user_endpoints.py +83 -7
  11. fides/api/app_setup.py +3 -2
  12. fides/api/common_exceptions.py +4 -0
  13. fides/api/db/base.py +1 -0
  14. fides/api/db/database.py +1 -1
  15. fides/api/graph/execution.py +30 -0
  16. fides/api/graph/traversal.py +1 -1
  17. fides/api/models/manual_task/__init__.py +2 -0
  18. fides/api/models/manual_task/conditional_dependency.py +144 -0
  19. fides/api/models/{manual_task.py → manual_task/manual_task.py} +10 -0
  20. fides/api/models/masking_secret.py +72 -0
  21. fides/api/models/policy.py +23 -0
  22. fides/api/models/privacy_request/execution_log.py +1 -0
  23. fides/api/models/privacy_request/privacy_request.py +31 -13
  24. fides/api/oauth/roles.py +2 -0
  25. fides/api/schemas/application_config.py +11 -1
  26. fides/api/schemas/masking/masking_secrets.py +1 -1
  27. fides/api/schemas/policy.py +1 -0
  28. fides/api/schemas/privacy_request.py +5 -0
  29. fides/api/service/connectors/base_connector.py +1 -0
  30. fides/api/service/connectors/bigquery_connector.py +67 -19
  31. fides/api/service/connectors/dynamodb_connector.py +2 -1
  32. fides/api/service/connectors/fides_connector.py +1 -0
  33. fides/api/service/connectors/http_connector.py +1 -0
  34. fides/api/service/connectors/manual_task_connector.py +1 -0
  35. fides/api/service/connectors/manual_webhook_connector.py +2 -1
  36. fides/api/service/connectors/mongodb_connector.py +1 -0
  37. fides/api/service/connectors/okta_connector.py +1 -0
  38. fides/api/service/connectors/query_configs/bigquery_query_config.py +91 -32
  39. fides/api/service/connectors/rds_mysql_connector.py +1 -0
  40. fides/api/service/connectors/rds_postgres_connector.py +1 -0
  41. fides/api/service/connectors/s3_connector.py +1 -0
  42. fides/api/service/connectors/saas_connector.py +1 -0
  43. fides/api/service/connectors/scylla_connector.py +1 -0
  44. fides/api/service/connectors/sql_connector.py +36 -4
  45. fides/api/service/connectors/website_connector.py +1 -0
  46. fides/api/service/privacy_request/request_runner_service.py +142 -53
  47. fides/api/service/privacy_request/request_service.py +1 -22
  48. fides/api/task/conditional_dependencies/__init__.py +0 -0
  49. fides/api/task/conditional_dependencies/evaluator.py +109 -0
  50. fides/api/task/conditional_dependencies/schemas.py +54 -0
  51. fides/api/task/create_request_tasks.py +1 -1
  52. fides/api/task/deprecated_graph_task.py +24 -6
  53. fides/api/task/execute_request_tasks.py +89 -12
  54. fides/api/task/filter_results.py +1 -1
  55. fides/api/task/graph_task.py +38 -3
  56. fides/api/task/manual/manual_task_address.py +46 -0
  57. fides/api/task/manual/manual_task_graph_task.py +118 -126
  58. fides/api/task/manual/manual_task_utils.py +52 -105
  59. fides/api/util/cache.py +5 -0
  60. fides/api/util/encryption/secrets_util.py +48 -18
  61. fides/common/api/scope_registry.py +3 -0
  62. fides/common/api/v1/urn_registry.py +1 -1
  63. fides/config/execution_settings.py +4 -0
  64. fides/config/utils.py +1 -0
  65. fides/service/privacy_request/privacy_request_service.py +6 -1
  66. fides/ui-build/static/admin/404.html +1 -1
  67. fides/ui-build/static/admin/_next/static/chunks/1817-6f35f58cd08b04ae.js +1 -0
  68. fides/ui-build/static/admin/_next/static/chunks/{203-5a663f465ba26bb4.js → 203-4e777c324a01dbec.js} +1 -1
  69. fides/ui-build/static/admin/_next/static/chunks/431-ade3e312fac3430b.js +1 -0
  70. fides/ui-build/static/admin/_next/static/chunks/6780-a00c87739acc004d.js +1 -0
  71. fides/ui-build/static/admin/_next/static/chunks/{796-329a5f823ec258a5.js → 796-3bdda2a7868464af.js} +1 -1
  72. fides/ui-build/static/admin/_next/static/chunks/8237-55049f8f5fd5e058.js +1 -0
  73. fides/ui-build/static/admin/_next/static/chunks/pages/{_app-39ccb07327c2c5d5.js → _app-f2c3d287bac00395.js} +56 -56
  74. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-71579a199158952e.js +1 -0
  75. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-7d3115059503b904.js +1 -0
  76. fides/ui-build/static/admin/_next/static/chunks/pages/{integrations-e2d5d7e2a5265e68.js → integrations-f10a7dcf7541c865.js} +1 -1
  77. fides/ui-build/static/admin/_next/static/chunks/pages/poc/{table-migration-69ad86b7a8a9a115.js → table-migration-05616e2ae20ff4f8.js} +1 -1
  78. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-c73497fc333c324d.js +1 -0
  79. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-7498d1d5974a78b0.js +1 -0
  80. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-2d3a2d967767a131.js +1 -0
  81. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-6a9068df48bdee05.js +1 -0
  82. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/[id]-fe58cebba358119d.js +1 -0
  83. fides/ui-build/static/admin/_next/static/css/{5bfb2473e5701527.css → 23cf870196941c9a.css} +1 -1
  84. fides/ui-build/static/admin/_next/static/css/79e296c724c1568c.css +1 -0
  85. fides/ui-build/static/admin/_next/static/css/{94965f224bc991e9.css → 8bc1833f1fa53ff0.css} +1 -1
  86. fides/ui-build/static/admin/_next/static/hKDMNIRKgB86FSDpiOjHn/_buildManifest.js +1 -0
  87. fides/ui-build/static/admin/add-systems/manual.html +1 -1
  88. fides/ui-build/static/admin/add-systems/multiple.html +1 -1
  89. fides/ui-build/static/admin/add-systems.html +1 -1
  90. fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
  91. fides/ui-build/static/admin/consent/configure.html +1 -1
  92. fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
  93. fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
  94. fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
  95. fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
  96. fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
  97. fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
  98. fides/ui-build/static/admin/consent/properties.html +1 -1
  99. fides/ui-build/static/admin/consent/reporting.html +1 -1
  100. fides/ui-build/static/admin/consent.html +1 -1
  101. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
  102. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
  103. fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
  104. fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
  105. fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
  106. fides/ui-build/static/admin/data-catalog.html +1 -1
  107. fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/[systemId].html +1 -1
  108. fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +1 -1
  109. fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
  110. fides/ui-build/static/admin/data-discovery/activity.html +1 -1
  111. fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
  112. fides/ui-build/static/admin/data-discovery/detection.html +1 -1
  113. fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
  114. fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
  115. fides/ui-build/static/admin/datamap.html +1 -1
  116. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
  117. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
  118. fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
  119. fides/ui-build/static/admin/dataset/new.html +1 -1
  120. fides/ui-build/static/admin/dataset.html +1 -1
  121. fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
  122. fides/ui-build/static/admin/datastore-connection/new.html +1 -1
  123. fides/ui-build/static/admin/datastore-connection.html +1 -1
  124. fides/ui-build/static/admin/index.html +1 -1
  125. fides/ui-build/static/admin/integrations/[id].html +1 -1
  126. fides/ui-build/static/admin/integrations.html +1 -1
  127. fides/ui-build/static/admin/lib/fides-ext-gpp.js +1 -1
  128. fides/ui-build/static/admin/lib/fides-headless.js +1 -1
  129. fides/ui-build/static/admin/lib/fides-preview.js +1 -1
  130. fides/ui-build/static/admin/lib/fides-tcf.js +3 -3
  131. fides/ui-build/static/admin/lib/fides.js +3 -3
  132. fides/ui-build/static/admin/login/[provider].html +1 -1
  133. fides/ui-build/static/admin/login.html +1 -1
  134. fides/ui-build/static/admin/messaging/[id].html +1 -1
  135. fides/ui-build/static/admin/messaging/add-template.html +1 -1
  136. fides/ui-build/static/admin/messaging.html +1 -1
  137. fides/ui-build/static/admin/poc/ant-components.html +1 -1
  138. fides/ui-build/static/admin/poc/form-experiments/AntForm.html +1 -1
  139. fides/ui-build/static/admin/poc/form-experiments/FormikAntFormItem.html +1 -1
  140. fides/ui-build/static/admin/poc/form-experiments/FormikControlled.html +1 -1
  141. fides/ui-build/static/admin/poc/form-experiments/FormikField.html +1 -1
  142. fides/ui-build/static/admin/poc/form-experiments/FormikSpreadField.html +1 -1
  143. fides/ui-build/static/admin/poc/forms.html +1 -1
  144. fides/ui-build/static/admin/poc/table-migration.html +1 -1
  145. fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
  146. fides/ui-build/static/admin/privacy-requests/configure/messaging.html +1 -1
  147. fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
  148. fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
  149. fides/ui-build/static/admin/privacy-requests.html +1 -1
  150. fides/ui-build/static/admin/properties/[id].html +1 -1
  151. fides/ui-build/static/admin/properties/add-property.html +1 -1
  152. fides/ui-build/static/admin/properties.html +1 -1
  153. fides/ui-build/static/admin/reporting/datamap.html +1 -1
  154. fides/ui-build/static/admin/settings/about/alpha.html +1 -1
  155. fides/ui-build/static/admin/settings/about.html +1 -1
  156. fides/ui-build/static/admin/settings/consent/[configuration_id]/[purpose_id].html +1 -1
  157. fides/ui-build/static/admin/settings/consent.html +1 -1
  158. fides/ui-build/static/admin/settings/custom-fields.html +1 -1
  159. fides/ui-build/static/admin/settings/domain-records.html +1 -1
  160. fides/ui-build/static/admin/settings/domains.html +1 -1
  161. fides/ui-build/static/admin/settings/email-templates.html +1 -1
  162. fides/ui-build/static/admin/settings/locations.html +1 -1
  163. fides/ui-build/static/admin/settings/organization.html +1 -1
  164. fides/ui-build/static/admin/settings/regulations.html +1 -1
  165. fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
  166. fides/ui-build/static/admin/systems/configure/[id].html +1 -1
  167. fides/ui-build/static/admin/systems.html +1 -1
  168. fides/ui-build/static/admin/taxonomy.html +1 -1
  169. fides/ui-build/static/admin/user-management/new.html +1 -1
  170. fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
  171. fides/ui-build/static/admin/user-management.html +1 -1
  172. fides/ui-build/static/admin/_next/static/8108ANFxs99VY7KZ_Xev2/_buildManifest.js +0 -1
  173. fides/ui-build/static/admin/_next/static/chunks/1817-e601e737e3cc7a0e.js +0 -1
  174. fides/ui-build/static/admin/_next/static/chunks/431-34f0b91c26f8d9ab.js +0 -1
  175. fides/ui-build/static/admin/_next/static/chunks/6780-e3d40aa17a4bf2e9.js +0 -1
  176. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-2265ecb899d45fbc.js +0 -1
  177. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-5d522637871ac6c8.js +0 -1
  178. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-32600543eb7b584f.js +0 -1
  179. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-10ce53ea356f8bad.js +0 -1
  180. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-5501bbb129fee9c4.js +0 -1
  181. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-cbe4c8f9096b6543.js +0 -1
  182. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/[id]-ff5738706da07801.js +0 -1
  183. fides/ui-build/static/admin/_next/static/css/2cadb5f62dcd7c2b.css +0 -1
  184. {ethyca_fides-2.66.2rc0.dist-info → ethyca_fides-2.66.3b0.dist-info}/WHEEL +0 -0
  185. {ethyca_fides-2.66.2rc0.dist-info → ethyca_fides-2.66.3b0.dist-info}/entry_points.txt +0 -0
  186. {ethyca_fides-2.66.2rc0.dist-info → ethyca_fides-2.66.3b0.dist-info}/licenses/LICENSE +0 -0
  187. {ethyca_fides-2.66.2rc0.dist-info → ethyca_fides-2.66.3b0.dist-info}/top_level.txt +0 -0
  188. /fides/ui-build/static/admin/_next/static/chunks/{2921-455e6357b74d2f76.js → 2921-86f1547ac40a5cdf.js} +0 -0
  189. /fides/ui-build/static/admin/_next/static/chunks/{3450-0ba194991d0cca88.js → 3450-1cc2bb07ed142203.js} +0 -0
  190. /fides/ui-build/static/admin/_next/static/chunks/{3855-e172870d3e21b0dd.js → 3855-e2fa6db53d32c3de.js} +0 -0
  191. /fides/ui-build/static/admin/_next/static/chunks/{3872-46cebf7ec1b31a2b.js → 3872-84b7e380b88b4454.js} +0 -0
  192. /fides/ui-build/static/admin/_next/static/chunks/{3923-6cc911dafccc5f63.js → 3923-13a6b4da2d51bf8f.js} +0 -0
  193. /fides/ui-build/static/admin/_next/static/chunks/{401-1b529d5800aa1f3a.js → 401-3cc1fee61494e3bd.js} +0 -0
  194. /fides/ui-build/static/admin/_next/static/chunks/{409-a257e14acebcd73b.js → 409-45a125437261580c.js} +0 -0
  195. /fides/ui-build/static/admin/_next/static/chunks/{4121-2bc09fc4ddbfe5cb.js → 4121-f50675521dfee6eb.js} +0 -0
  196. /fides/ui-build/static/admin/_next/static/chunks/{4230-60100f7ef3ddcde1.js → 4230-840c287045c88b34.js} +0 -0
  197. /fides/ui-build/static/admin/_next/static/chunks/{4608-bbb7bf511a05c3c2.js → 4608-a8e3100e2806dbff.js} +0 -0
  198. /fides/ui-build/static/admin/_next/static/chunks/{5309-b2c4803370634ff8.js → 5309-1172322bf91b5d57.js} +0 -0
  199. /fides/ui-build/static/admin/_next/static/chunks/{5574-b13021775a15bfd2.js → 5574-9312f97b637d9ee2.js} +0 -0
  200. /fides/ui-build/static/admin/_next/static/chunks/{6084-7178ff6ea6822475.js → 6084-5d7598b7bcb548cf.js} +0 -0
  201. /fides/ui-build/static/admin/_next/static/chunks/{6662-507be5d46e5b719b.js → 6662-efb2cf74641647f2.js} +0 -0
  202. /fides/ui-build/static/admin/_next/static/chunks/{6853-2ad3e08fe6f9f5f2.js → 6853-4f8bf6558f8c6a46.js} +0 -0
  203. /fides/ui-build/static/admin/_next/static/chunks/{6882-6af16fef26c21e06.js → 6882-586b84aeb02d5830.js} +0 -0
  204. /fides/ui-build/static/admin/_next/static/chunks/{6954-bb875d9ac89f6030.js → 6954-34e062e4bffc7e71.js} +0 -0
  205. /fides/ui-build/static/admin/_next/static/chunks/{7476-281ee9a8286556f3.js → 7476-d206c11823c91088.js} +0 -0
  206. /fides/ui-build/static/admin/_next/static/chunks/{7630-9aac73191ed5ed13.js → 7630-b1c93688013ef013.js} +0 -0
  207. /fides/ui-build/static/admin/_next/static/chunks/{787-fb41002f797eb2df.js → 787-cbe2d0bfb513d90a.js} +0 -0
  208. /fides/ui-build/static/admin/_next/static/chunks/{79-7e87aff851423d4a.js → 79-3db1941d274f40c7.js} +0 -0
  209. /fides/ui-build/static/admin/_next/static/chunks/{9046-5c4c22c375de25b1.js → 9046-c8233981762585b4.js} +0 -0
  210. /fides/ui-build/static/admin/_next/static/chunks/{9226-746771d47dff6266.js → 9226-72ad691ca57b83ef.js} +0 -0
  211. /fides/ui-build/static/admin/_next/static/chunks/{9826-111aaee8bd8dbd09.js → 9826-3c578665c6d3b21d.js} +0 -0
  212. /fides/ui-build/static/admin/_next/static/chunks/{9951-9b753ad7c3f51bdf.js → 9951-595d0f1588215081.js} +0 -0
  213. /fides/ui-build/static/admin/_next/static/chunks/pages/{404-aece2c920ea14514.js → 404-2d803dab6a00f353.js} +0 -0
  214. /fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{manual-98777246bec9dc2a.js → manual-acb59f8b5e97512a.js} +0 -0
  215. /fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{multiple-dc75dc6e37e52f05.js → multiple-8ff7f37913ad736a.js} +0 -0
  216. /fides/ui-build/static/admin/_next/static/chunks/pages/{add-systems-a71c0aff4e0e6535.js → add-systems-0943633a8e422695.js} +0 -0
  217. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-24d226b5a8de5c74.js → add-vendors-d00c9034cdeb0236.js} +0 -0
  218. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{configure-6a8ef51138ac926a.js → configure-0e1ca0f4c8e7f4da.js} +0 -0
  219. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-1edf582ba3cd3bbb.js → [id]-fc3a011154a2e1de.js} +0 -0
  220. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-experience-685771e5f7196d87.js → privacy-experience-09d4408014bcfe1c.js} +0 -0
  221. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-6ccedc70dc447089.js → [id]-d67542783ef5ddac.js} +0 -0
  222. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-944bca1cc57985b5.js → new-3f20e8a316bb3d5b.js} +0 -0
  223. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-notices-84f4bd14ce8673bc.js → privacy-notices-23e9dcd4590312d2.js} +0 -0
  224. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{properties-6f86ab63a08a6528.js → properties-057cad65e7414a44.js} +0 -0
  225. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{reporting-afdbd4665657cfa1.js → reporting-8f891957c8944137.js} +0 -0
  226. /fides/ui-build/static/admin/_next/static/chunks/pages/{consent-73d3cbf68f7c3a31.js → consent-e17c56eec8d91371.js} +0 -0
  227. /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/{[resourceUrn]-11d52f1570759c4d.js → [resourceUrn]-99c9092d65c94807.js} +0 -0
  228. /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/{[projectUrn]-6ba9e160dae64695.js → [projectUrn]-80a6cc8e8573514a.js} +0 -0
  229. /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{projects-32eac8bbd217615a.js → projects-774fecea22ba8852.js} +0 -0
  230. /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/{[resourceUrn]-b83afa5565d0c84e.js → [resourceUrn]-f6bd6aff389cb9fe.js} +0 -0
  231. /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{resources-7648bbd4f6711e4d.js → resources-6c3714ee97a718c1.js} +0 -0
  232. /fides/ui-build/static/admin/_next/static/chunks/pages/{data-catalog-6f630d42ac9fb6b4.js → data-catalog-8a7f9285da66b965.js} +0 -0
  233. /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{action-center-9ddb52ebb7ac4c71.js → action-center-85e140788e251272.js} +0 -0
  234. /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{activity-9aa744d56cdacb0d.js → activity-5af9381f02b2aff6.js} +0 -0
  235. /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-393e20924c83373e.js → [resourceUrn]-31e6c54794a9883e.js} +0 -0
  236. /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-8733807dad4bc96e.js → detection-2822a423a7ad0550.js} +0 -0
  237. /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-14bd7500362ff224.js → [resourceUrn]-6421ce247549c5d6.js} +0 -0
  238. /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-9e7dfd5a6acc2e8f.js → discovery-3eac407ac5181a3c.js} +0 -0
  239. /fides/ui-build/static/admin/_next/static/chunks/pages/{datamap-7674b97d655c193b.js → datamap-d2b275d83089820d.js} +0 -0
  240. /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/{[...subfieldNames]-c0d2bfd465df20e0.js → [...subfieldNames]-1c98bd0959d9570a.js} +0 -0
  241. /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/{[collectionName]-28280a8a39a6e37c.js → [collectionName]-e548cabda7da32c9.js} +0 -0
  242. /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{[datasetId]-006b695e5af5ef24.js → [datasetId]-a8e8b5f4ee7af86c.js} +0 -0
  243. /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{new-82fb246d87e58ebd.js → new-513c862c3a707735.js} +0 -0
  244. /fides/ui-build/static/admin/_next/static/chunks/pages/{dataset-20165c31ab1bc7cf.js → dataset-747b7a13289f1cd7.js} +0 -0
  245. /fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{[id]-b4a6bcc87d126840.js → [id]-3d22525b3c327b2e.js} +0 -0
  246. /fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{new-f95d7b0bbfc58f5a.js → new-d2cad97495e86adb.js} +0 -0
  247. /fides/ui-build/static/admin/_next/static/chunks/pages/{datastore-connection-c391c6fad56eec48.js → datastore-connection-0f29b47402292070.js} +0 -0
  248. /fides/ui-build/static/admin/_next/static/chunks/pages/{index-1919aab9e5834b51.js → index-12ac3e317fc86f21.js} +0 -0
  249. /fides/ui-build/static/admin/_next/static/chunks/pages/integrations/{[id]-0a58aee2d1e7fa01.js → [id]-f9c0eac932188593.js} +0 -0
  250. /fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{[id]-53fecfb9dd6a1e0c.js → [id]-5627d0d0668077f9.js} +0 -0
  251. /fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{add-template-76b01cec5fde10a9.js → add-template-feca66ad5c5fe54a.js} +0 -0
  252. /fides/ui-build/static/admin/_next/static/chunks/pages/{messaging-5094ffea13f32ed9.js → messaging-c1bd3e7adbe8d2d3.js} +0 -0
  253. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{ant-components-5c08e8447c45ce44.js → ant-components-64a322d01aae5ca7.js} +0 -0
  254. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{AntForm-06ad5f34585480aa.js → AntForm-8bca16a7726e7eb2.js} +0 -0
  255. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikAntFormItem-6f071c2bc9446cb0.js → FormikAntFormItem-b0f246fc3b67ebf7.js} +0 -0
  256. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikControlled-efcc38c58991ac9e.js → FormikControlled-1a0852b090bfc392.js} +0 -0
  257. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikField-430ba5c979abfb7c.js → FormikField-11f3de1b45e36583.js} +0 -0
  258. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{forms-5c561880bf131afb.js → forms-1b73a1c2b6c6285f.js} +0 -0
  259. /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{configure-d888a69a3bbe040e.js → configure-e551a860ec727802.js} +0 -0
  260. /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-d3d8e3d7583ec635.js → [id]-dd99183f93763ae4.js} +0 -0
  261. /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-1af10ed303815d46.js → add-property-0bdbc1fcbf553b8f.js} +0 -0
  262. /fides/ui-build/static/admin/_next/static/chunks/pages/{properties-cebc0dc186be499a.js → properties-e959378bb32b6b73.js} +0 -0
  263. /fides/ui-build/static/admin/_next/static/chunks/pages/reporting/{datamap-e130c0197362e8f3.js → datamap-2a98bd257edd8f47.js} +0 -0
  264. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/{alpha-5e1322de868d615e.js → alpha-8f98a4895e74725e.js} +0 -0
  265. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{about-241f95e372b65d0f.js → about-8155a35a62fdb5ae.js} +0 -0
  266. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/{[purpose_id]-fc201657f4a782c7.js → [purpose_id]-668d74c041d74650.js} +0 -0
  267. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{consent-c2d39cba8396ef3a.js → consent-a989532a12c40dcf.js} +0 -0
  268. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{custom-fields-d992103cc55901ae.js → custom-fields-45bea76ff7eda3cb.js} +0 -0
  269. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-41242f805599feda.js → domain-records-51333dbd21cb37c8.js} +0 -0
  270. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domains-2e885f74c92f669c.js → domains-bde86e5f6c09da5a.js} +0 -0
  271. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{email-templates-ff112655ad5f41e5.js → email-templates-4f9a5cc8bea7725b.js} +0 -0
  272. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-023e1895552817de.js → locations-6946e78a5d43e654.js} +0 -0
  273. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{organization-ac403c0886b20e20.js → organization-55a10e01dffc8039.js} +0 -0
  274. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-86062a18e081a52a.js → regulations-102efd9199e87124.js} +0 -0
  275. /fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/{test-datasets-7a3396ac819c7904.js → test-datasets-f91f22cf96566ed4.js} +0 -0
  276. /fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-8314a819837f5b2a.js → [id]-d4a57ea18935dd70.js} +0 -0
  277. /fides/ui-build/static/admin/_next/static/chunks/pages/{systems-21f423a7c417aa9d.js → systems-648a0ff4920579ce.js} +0 -0
  278. /fides/ui-build/static/admin/_next/static/chunks/pages/{taxonomy-6387fcc8cce872eb.js → taxonomy-0b9d1a24188f65a9.js} +0 -0
  279. /fides/ui-build/static/admin/_next/static/chunks/pages/user-management/{new-a2524414e968f862.js → new-bc4eb541906781e6.js} +0 -0
  280. /fides/ui-build/static/admin/_next/static/chunks/pages/{user-management-173ac3a1ed2b05a6.js → user-management-45bfa04e45a7d13f.js} +0 -0
  281. /fides/ui-build/static/admin/_next/static/chunks/{webpack-ff0cd6bff75588da.js → webpack-63a0c45b150a1037.js} +0 -0
  282. /fides/ui-build/static/admin/_next/static/{8108ANFxs99VY7KZ_Xev2 → hKDMNIRKgB86FSDpiOjHn}/_ssgManifest.js +0 -0
@@ -1,4 +1,4 @@
1
- from typing import Any, Dict, List, Optional
1
+ from typing import Any, Optional
2
2
 
3
3
  from loguru import logger
4
4
  from sqlalchemy.orm import Session
@@ -18,9 +18,9 @@ from fides.api.models.privacy_request import PrivacyRequest
18
18
  from fides.api.schemas.policy import ActionType
19
19
  from fides.api.schemas.privacy_request import PrivacyRequestStatus
20
20
  from fides.api.task.graph_task import GraphTask, retry
21
+ from fides.api.task.manual.manual_task_address import ManualTaskAddress
21
22
  from fides.api.task.manual.manual_task_utils import (
22
- ManualTaskAddress,
23
- get_manual_tasks_for_connection_config,
23
+ get_manual_task_for_connection_config,
24
24
  )
25
25
  from fides.api.util.collection_util import Row
26
26
 
@@ -29,7 +29,7 @@ class ManualTaskGraphTask(GraphTask):
29
29
  """GraphTask implementation for ManualTask execution"""
30
30
 
31
31
  @retry(action_type=ActionType.access, default_return=[])
32
- def access_request(self, *inputs: List[Row]) -> List[Row]:
32
+ def access_request(self, *inputs: list[Row]) -> list[Row]:
33
33
  """
34
34
  Execute manual task logic following the standard GraphTask pattern:
35
35
  1. Create ManualTaskInstances if they don't exist
@@ -46,9 +46,9 @@ class ManualTaskGraphTask(GraphTask):
46
46
  connection_key = ManualTaskAddress.get_connection_key(collection_address)
47
47
 
48
48
  # Get manual tasks for this connection
49
- manual_tasks = get_manual_tasks_for_connection_config(db, connection_key)
49
+ manual_task = get_manual_task_for_connection_config(db, connection_key)
50
50
 
51
- if not manual_tasks:
51
+ if not manual_task:
52
52
  return []
53
53
 
54
54
  # Check if any manual tasks have ACCESS configs
@@ -56,7 +56,6 @@ class ManualTaskGraphTask(GraphTask):
56
56
 
57
57
  has_access_configs = [
58
58
  config
59
- for manual_task in manual_tasks
60
59
  for config in manual_task.configs
61
60
  if config.is_current
62
61
  and config.config_type == ManualTaskConfigurationType.access_privacy_request
@@ -77,7 +76,7 @@ class ManualTaskGraphTask(GraphTask):
77
76
  # Check/create manual task instances for ACCESS configs only
78
77
  self._ensure_manual_task_instances(
79
78
  db,
80
- manual_tasks,
79
+ manual_task,
81
80
  self.resources.request,
82
81
  ManualTaskConfigurationType.access_privacy_request,
83
82
  )
@@ -85,13 +84,13 @@ class ManualTaskGraphTask(GraphTask):
85
84
  # Check if all manual task instances have submissions for ACCESS configs only
86
85
  submitted_data = self._get_submitted_data(
87
86
  db,
88
- manual_tasks,
87
+ manual_task,
89
88
  self.resources.request,
90
89
  ManualTaskConfigurationType.access_privacy_request,
91
90
  )
92
91
 
93
92
  if submitted_data is not None:
94
- result: List[Row] = [submitted_data] if submitted_data else []
93
+ result: list[Row] = [submitted_data] if submitted_data else []
95
94
  self.request_task.access_data = result
96
95
 
97
96
  # Mark request task as complete and write execution log
@@ -111,67 +110,65 @@ class ManualTaskGraphTask(GraphTask):
111
110
  def _ensure_manual_task_instances(
112
111
  self,
113
112
  db: Session,
114
- manual_tasks: List[ManualTask],
113
+ manual_task: ManualTask,
115
114
  privacy_request: PrivacyRequest,
116
115
  allowed_config_type: "ManualTaskConfigurationType",
117
116
  ) -> None:
118
117
  """Create ManualTaskInstances for configs matching `allowed_config_type` if they don't exist."""
119
118
 
120
- for manual_task in manual_tasks:
121
- # ------------------------------------------------------------------
122
- # Check if instances already exist for this task & entity with the SAME config type
123
- # This prevents duplicates when configurations are versioned after the privacy
124
- # request has started, while allowing different config types (access vs erasure)
125
- # to have separate instances.
126
- # ------------------------------------------------------------------
127
- existing_task_instance = (
128
- db.query(ManualTaskInstance)
129
- .join(ManualTaskInstance.config) # Join to access config information
130
- .filter(
131
- ManualTaskInstance.task_id == manual_task.id,
132
- ManualTaskInstance.entity_id == privacy_request.id,
133
- ManualTaskInstance.entity_type
134
- == ManualTaskEntityType.privacy_request,
135
- # Only check for instances of the same config type
136
- ManualTaskConfig.config_type == allowed_config_type,
137
- )
138
- .first()
119
+ # ------------------------------------------------------------------
120
+ # Check if instances already exist for this task & entity with the SAME config type
121
+ # This prevents duplicates when configurations are versioned after the privacy
122
+ # request has started, while allowing different config types (access vs erasure)
123
+ # to have separate instances.
124
+ # ------------------------------------------------------------------
125
+ existing_task_instance = (
126
+ db.query(ManualTaskInstance)
127
+ .join(ManualTaskInstance.config) # Join to access config information
128
+ .filter(
129
+ ManualTaskInstance.task_id == manual_task.id,
130
+ ManualTaskInstance.entity_id == privacy_request.id,
131
+ ManualTaskInstance.entity_type == ManualTaskEntityType.privacy_request,
132
+ # Only check for instances of the same config type
133
+ ManualTaskConfig.config_type == allowed_config_type,
139
134
  )
140
- if existing_task_instance:
141
- # An instance already exists for this privacy request and config type – no need
142
- # to create another one tied to a newer config version.
135
+ .first()
136
+ )
137
+ if existing_task_instance:
138
+ # An instance already exists for this privacy request and config type – no need
139
+ # to create another one tied to a newer config version.
140
+ return
141
+
142
+ # Check each active config for instances (now we know none exist yet for this config type)
143
+ for config in manual_task.configs:
144
+ if not config.is_current or config.config_type != allowed_config_type:
145
+ # Skip configs that are not current or not relevant for this request type
143
146
  continue
144
147
 
145
- # Check each active config for instances (now we know none exist yet for this config type)
146
- for config in manual_task.configs:
147
- if not config.is_current or config.config_type != allowed_config_type:
148
- # Skip configs that are not current or not relevant for this request type
149
- continue
150
-
151
- ManualTaskInstance.create(
152
- db=db,
153
- data={
154
- "task_id": manual_task.id,
155
- "config_id": config.id,
156
- "entity_id": privacy_request.id,
157
- "entity_type": ManualTaskEntityType.privacy_request.value,
158
- "status": StatusType.pending.value,
159
- },
160
- )
148
+ ManualTaskInstance.create(
149
+ db=db,
150
+ data={
151
+ "task_id": manual_task.id,
152
+ "config_id": config.id,
153
+ "entity_id": privacy_request.id,
154
+ "entity_type": ManualTaskEntityType.privacy_request.value,
155
+ "status": StatusType.pending.value,
156
+ },
157
+ )
161
158
 
162
159
  # pylint: disable=too-many-branches,too-many-nested-blocks
163
160
  def _get_submitted_data(
164
161
  self,
165
162
  db: Session,
166
- manual_tasks: List[ManualTask],
163
+ manual_task: ManualTask,
167
164
  privacy_request: PrivacyRequest,
168
165
  allowed_config_type: "ManualTaskConfigurationType",
169
- ) -> Optional[Dict[str, Any]]:
166
+ ) -> Optional[dict[str, Any]]:
170
167
  """
171
168
  Check if all manual task instances have submissions for ALL fields and return aggregated data
172
169
  Returns None if any field submissions are missing (all fields must be completed or skipped)
173
170
  """
174
- aggregated_data: Dict[str, Any] = {}
171
+ aggregated_data: dict[str, Any] = {}
175
172
 
176
173
  def _format_size(size_bytes: int) -> str:
177
174
  units = ["B", "KB", "MB", "GB", "TB"]
@@ -182,79 +179,74 @@ class ManualTaskGraphTask(GraphTask):
182
179
  size /= 1024.0
183
180
  return f"{size:.1f} PB"
184
181
 
185
- for manual_task in manual_tasks:
186
-
187
- candidate_instances: list[ManualTaskInstance] = (
188
- db.query(ManualTaskInstance)
189
- .filter(
190
- ManualTaskInstance.task_id == manual_task.id,
191
- ManualTaskInstance.entity_id == privacy_request.id,
192
- ManualTaskInstance.entity_type
193
- == ManualTaskEntityType.privacy_request,
194
- )
195
- .all()
182
+ candidate_instances: list[ManualTaskInstance] = (
183
+ db.query(ManualTaskInstance)
184
+ .filter(
185
+ ManualTaskInstance.task_id == manual_task.id,
186
+ ManualTaskInstance.entity_id == privacy_request.id,
187
+ ManualTaskInstance.entity_type == ManualTaskEntityType.privacy_request,
196
188
  )
189
+ .all()
190
+ )
191
+
192
+ if not candidate_instances:
193
+ return None # No instance yet for this manual task
194
+
195
+ for inst in candidate_instances:
196
+ # Skip instances tied to other request types
197
+ if not inst.config or inst.config.config_type != allowed_config_type:
198
+ continue
199
+
200
+ all_fields = inst.config.field_definitions or []
201
+
202
+ # Every field must have a submission
203
+ if not all(inst.get_submission_for_field(f.id) for f in all_fields):
204
+ return None # At least one instance still incomplete
205
+
206
+ # Ensure status set
207
+ if inst.status != StatusType.completed:
208
+ inst.status = StatusType.completed
209
+ inst.save(db)
210
+
211
+ # Aggregate submission data from this instance
212
+ for submission in inst.submissions:
213
+ if not submission.field or not submission.field.field_key:
214
+ continue
197
215
 
198
- if not candidate_instances:
199
- return None # No instance yet for this manual task
216
+ field_key = submission.field.field_key
200
217
 
201
- for inst in candidate_instances:
202
- # Skip instances tied to other request types
203
- if not inst.config or inst.config.config_type != allowed_config_type:
218
+ if not isinstance(submission.data, dict):
204
219
  continue
205
220
 
206
- all_fields = inst.config.field_definitions or []
207
-
208
- # Every field must have a submission
209
- if not all(inst.get_submission_for_field(f.id) for f in all_fields):
210
- return None # At least one instance still incomplete
211
-
212
- # Ensure status set
213
- if inst.status != StatusType.completed:
214
- inst.status = StatusType.completed
215
- inst.save(db)
216
-
217
- # Aggregate submission data from this instance
218
- for submission in inst.submissions:
219
- if not submission.field or not submission.field.field_key:
220
- continue
221
-
222
- field_key = submission.field.field_key
223
-
224
- if not isinstance(submission.data, dict):
225
- continue
226
-
227
- data_dict: Dict[str, Any] = submission.data
228
-
229
- field_type = data_dict.get("field_type")
230
-
231
- if field_type == ManualTaskFieldType.attachment.value:
232
- attachment_map: Dict[str, Dict[str, Any]] = {}
233
- for attachment in submission.attachments or []:
234
- if (
235
- attachment.attachment_type
236
- == AttachmentType.include_with_access_package
237
- ):
238
- try:
239
- size, url = attachment.retrieve_attachment()
240
- attachment_map[attachment.file_name] = {
241
- "url": str(url) if url else None,
242
- "size": (
243
- _format_size(size) if size else "Unknown"
244
- ),
245
- }
246
- except (
247
- Exception
248
- ) as exc: # pylint: disable=broad-exception-caught
249
- logger.warning(
250
- "Error retrieving attachment {}: {}",
251
- attachment.file_name,
252
- str(exc),
253
- )
254
-
255
- aggregated_data[field_key] = attachment_map or None
256
- else:
257
- aggregated_data[field_key] = data_dict.get("value")
221
+ data_dict: dict[str, Any] = submission.data
222
+
223
+ field_type = data_dict.get("field_type")
224
+
225
+ if field_type == ManualTaskFieldType.attachment.value:
226
+ attachment_map: dict[str, dict[str, Any]] = {}
227
+ for attachment in submission.attachments or []:
228
+ if (
229
+ attachment.attachment_type
230
+ == AttachmentType.include_with_access_package
231
+ ):
232
+ try:
233
+ size, url = attachment.retrieve_attachment()
234
+ attachment_map[attachment.file_name] = {
235
+ "url": str(url) if url else None,
236
+ "size": (_format_size(size) if size else "Unknown"),
237
+ }
238
+ except (
239
+ Exception
240
+ ) as exc: # pylint: disable=broad-exception-caught
241
+ logger.warning(
242
+ "Error retrieving attachment {}: {}",
243
+ attachment.file_name,
244
+ str(exc),
245
+ )
246
+
247
+ aggregated_data[field_key] = attachment_map or None
248
+ else:
249
+ aggregated_data[field_key] = data_dict.get("value")
258
250
 
259
251
  return aggregated_data if aggregated_data else None
260
252
 
@@ -266,8 +258,9 @@ class ManualTaskGraphTask(GraphTask):
266
258
  @retry(action_type=ActionType.erasure, default_return=0)
267
259
  def erasure_request(
268
260
  self,
269
- retrieved_data: List[Row],
261
+ retrieved_data: list[Row],
270
262
  *erasure_prereqs: int, # noqa: D401, pylint: disable=unused-argument
263
+ inputs: Optional[list[list[Row]]] = None,
271
264
  ) -> int:
272
265
  """Execute manual-task-driven erasure logic.
273
266
 
@@ -285,8 +278,8 @@ class ManualTaskGraphTask(GraphTask):
285
278
  connection_key = ManualTaskAddress.get_connection_key(collection_address)
286
279
 
287
280
  # Fetch relevant manual tasks for this connection
288
- manual_tasks = get_manual_tasks_for_connection_config(db, connection_key)
289
- if not manual_tasks:
281
+ manual_task = get_manual_task_for_connection_config(db, connection_key)
282
+ if not manual_task:
290
283
  # No manual tasks defined – nothing to erase
291
284
  self.log_end(ActionType.erasure)
292
285
  return 0
@@ -294,7 +287,6 @@ class ManualTaskGraphTask(GraphTask):
294
287
  # Check if any manual tasks have ERASURE configs
295
288
  has_erasure_configs = [
296
289
  config
297
- for manual_task in manual_tasks
298
290
  for config in manual_task.configs
299
291
  if config.is_current
300
292
  and config.config_type
@@ -309,7 +301,7 @@ class ManualTaskGraphTask(GraphTask):
309
301
  # Create ManualTaskInstances for ERASURE configs only
310
302
  self._ensure_manual_task_instances(
311
303
  db,
312
- manual_tasks,
304
+ manual_task,
313
305
  self.resources.request,
314
306
  ManualTaskConfigurationType.erasure_privacy_request,
315
307
  )
@@ -317,7 +309,7 @@ class ManualTaskGraphTask(GraphTask):
317
309
  # Check for full submissions – reuse helper used by access flow, filtering ERASURE configs
318
310
  submissions_complete = self._get_submitted_data(
319
311
  db,
320
- manual_tasks,
312
+ manual_task,
321
313
  self.resources.request,
322
314
  ManualTaskConfigurationType.erasure_privacy_request,
323
315
  )
@@ -1,5 +1,3 @@
1
- from typing import TYPE_CHECKING, List
2
-
3
1
  from sqlalchemy.orm import Session
4
2
 
5
3
  from fides.api.graph.config import (
@@ -10,6 +8,7 @@ from fides.api.graph.config import (
10
8
  ScalarField,
11
9
  )
12
10
  from fides.api.graph.graph import Node
11
+ from fides.api.graph.traversal import TraversalNode
13
12
  from fides.api.models.connectionconfig import ConnectionConfig
14
13
 
15
14
  # Import application models
@@ -22,51 +21,10 @@ from fides.api.models.manual_task import (
22
21
  )
23
22
  from fides.api.models.privacy_request import PrivacyRequest
24
23
  from fides.api.schemas.policy import ActionType
24
+ from fides.api.task.manual.manual_task_address import ManualTaskAddress
25
25
 
26
- # TYPE_CHECKING import placed after all runtime imports to avoid lint issues
27
- if TYPE_CHECKING: # pragma: no cover
28
- from fides.api.graph.traversal import TraversalNode # noqa: F401
29
- from fides.api.models.policy import Policy # noqa: F401
30
-
31
-
32
- class ManualTaskAddress:
33
- """Utility class for creating and parsing manual task addresses"""
34
-
35
- MANUAL_DATA_COLLECTION = "manual_data"
36
-
37
- @staticmethod
38
- def create(connection_config_key: str) -> CollectionAddress:
39
- """Create a CollectionAddress for manual data: {connection_key}:manual_data"""
40
- return CollectionAddress(
41
- dataset=connection_config_key,
42
- collection=ManualTaskAddress.MANUAL_DATA_COLLECTION,
43
- )
44
-
45
- @staticmethod
46
- def is_manual_task_address(address: CollectionAddress) -> bool:
47
- """Check if address represents manual task data"""
48
- if isinstance(address, str):
49
- # Handle string format "connection_key:collection_name"
50
- return address.endswith(f":{ManualTaskAddress.MANUAL_DATA_COLLECTION}")
51
-
52
- # Handle CollectionAddress object
53
- return address.collection == ManualTaskAddress.MANUAL_DATA_COLLECTION
54
-
55
- @staticmethod
56
- def get_connection_key(address: CollectionAddress) -> str:
57
- """Extract connection config key from manual task address"""
58
- if not ManualTaskAddress.is_manual_task_address(address):
59
- raise ValueError(f"Not a manual task address: {address}")
60
-
61
- if isinstance(address, str):
62
- # Handle string format "connection_key:collection_name"
63
- return address.split(":")[0]
64
-
65
- # Handle CollectionAddress object
66
- return address.dataset
67
26
 
68
-
69
- def get_connection_configs_with_manual_tasks(db: Session) -> List[ConnectionConfig]:
27
+ def get_connection_configs_with_manual_tasks(db: Session) -> list[ConnectionConfig]:
70
28
  """
71
29
  Get all connection configs that have manual tasks.
72
30
  """
@@ -79,7 +37,7 @@ def get_connection_configs_with_manual_tasks(db: Session) -> List[ConnectionConf
79
37
  )
80
38
 
81
39
 
82
- def get_manual_task_addresses(db: Session) -> List[CollectionAddress]:
40
+ def get_manual_task_addresses(db: Session) -> list[CollectionAddress]:
83
41
  """
84
42
  Get manual task addresses for all connection configs that have manual tasks.
85
43
 
@@ -98,26 +56,20 @@ def get_manual_task_addresses(db: Session) -> List[CollectionAddress]:
98
56
  return manual_task_addresses
99
57
 
100
58
 
101
- def get_manual_tasks_for_connection_config(
59
+ def get_manual_task_for_connection_config(
102
60
  db: Session, connection_config_key: str
103
- ) -> List[ManualTask]:
104
- """Get all ManualTasks for a specific connection config"""
105
- connection_config = (
106
- db.query(ConnectionConfig)
107
- .filter(ConnectionConfig.key == connection_config_key)
108
- .first()
109
- )
110
-
111
- if not connection_config:
112
- return []
113
-
61
+ ) -> ManualTask:
62
+ """Get the ManualTask for a specific connection config,
63
+ the manual task/connection config relationship is 1:1.
64
+ """
114
65
  return (
115
66
  db.query(ManualTask)
67
+ .join(ConnectionConfig, ManualTask.parent_entity_id == ConnectionConfig.id)
116
68
  .filter(
117
- ManualTask.parent_entity_id == connection_config.id,
69
+ ConnectionConfig.key == connection_config_key,
118
70
  ManualTask.parent_entity_type == "connection_config",
119
71
  )
120
- .all()
72
+ .one_or_none()
121
73
  )
122
74
 
123
75
 
@@ -130,24 +82,23 @@ def create_manual_data_traversal_node(
130
82
  connection_key = address.dataset
131
83
 
132
84
  # Get manual tasks for this connection to determine fields
133
- manual_tasks = get_manual_tasks_for_connection_config(db, connection_key)
85
+ manual_task = get_manual_task_for_connection_config(db, connection_key)
134
86
 
135
87
  # Create fields based on ManualTaskConfigFields
136
- fields: List[Field] = []
137
- for manual_task in manual_tasks:
138
- for config in manual_task.configs:
139
- for field in config.field_definitions:
140
- # Create a scalar field for each manual task field
141
- # Extract data categories from field metadata if available
142
- field_metadata = field.field_metadata or {}
143
- data_categories = field_metadata.get("data_categories", [])
144
-
145
- scalar_field = ScalarField(
146
- name=field.field_key,
147
- data_categories=data_categories,
148
- # Manual task fields don't have complex relationships
149
- )
150
- fields.append(scalar_field)
88
+ fields: list[Field] = []
89
+ for config in manual_task.configs:
90
+ for field in config.field_definitions:
91
+ # Create a scalar field for each manual task field
92
+ # Extract data categories from field metadata if available
93
+ field_metadata = field.field_metadata or {}
94
+ data_categories = field_metadata.get("data_categories", [])
95
+
96
+ scalar_field = ScalarField(
97
+ name=field.field_key,
98
+ data_categories=data_categories,
99
+ # Manual task fields don't have complex relationships
100
+ )
101
+ fields.append(scalar_field)
151
102
 
152
103
  # Create a synthetic Collection
153
104
  collection = Collection(
@@ -165,9 +116,6 @@ def create_manual_data_traversal_node(
165
116
  after=set(),
166
117
  )
167
118
 
168
- # Create Node and TraversalNode (import locally to avoid cyclic import)
169
- from fides.api.graph.traversal import TraversalNode # local import
170
-
171
119
  node = Node(dataset, collection)
172
120
  traversal_node = TraversalNode(node)
173
121
 
@@ -176,7 +124,7 @@ def create_manual_data_traversal_node(
176
124
 
177
125
  def create_manual_task_instances_for_privacy_request(
178
126
  db: Session, privacy_request: PrivacyRequest
179
- ) -> List[ManualTaskInstance]:
127
+ ) -> list[ManualTaskInstance]:
180
128
  """Create ManualTaskInstance entries for all active manual tasks relevant to a privacy request."""
181
129
  instances = []
182
130
 
@@ -272,7 +220,7 @@ def create_manual_task_instances_for_privacy_request(
272
220
 
273
221
  def get_manual_task_instances_for_privacy_request(
274
222
  db: Session, privacy_request: PrivacyRequest
275
- ) -> List[ManualTaskInstance]:
223
+ ) -> list[ManualTaskInstance]:
276
224
  """Get all manual task instances for a privacy request."""
277
225
  return (
278
226
  db.query(ManualTaskInstance)
@@ -286,7 +234,7 @@ def get_manual_task_instances_for_privacy_request(
286
234
 
287
235
  def create_manual_task_artificial_graphs(
288
236
  db: Session,
289
- ) -> List:
237
+ ) -> list:
290
238
  """
291
239
  Create artificial GraphDataset objects for manual tasks that can be included
292
240
  in the main dataset graph during the dataset configuration phase.
@@ -313,34 +261,33 @@ def create_manual_task_artificial_graphs(
313
261
  connection_key = address.dataset
314
262
 
315
263
  # Get manual tasks for this connection to determine fields
316
- manual_tasks = get_manual_tasks_for_connection_config(db, connection_key)
264
+ manual_task = get_manual_task_for_connection_config(db, connection_key)
317
265
 
318
266
  # Create fields based only on ManualTaskConfigFields
319
- fields: List = []
267
+ fields: list = []
320
268
 
321
269
  # Manual task collections act as root nodes - they don't need identity dependencies
322
270
  # since they provide manually-entered data rather than consuming identity data.
323
- for manual_task in manual_tasks:
324
- current_configs = [
325
- config for config in manual_task.configs if config.is_current
326
- ]
327
- for config in current_configs:
328
- if config.config_type not in [
329
- ManualTaskConfigurationType.access_privacy_request,
330
- ManualTaskConfigurationType.erasure_privacy_request,
331
- ]:
332
- continue
333
-
334
- for field in config.field_definitions:
335
- # Create a scalar field for each manual task field
336
- field_metadata = field.field_metadata or {}
337
- data_categories = field_metadata.get("data_categories", [])
338
-
339
- scalar_field = ScalarField(
340
- name=field.field_key,
341
- data_categories=data_categories,
342
- )
343
- fields.append(scalar_field)
271
+ current_configs = [
272
+ config for config in manual_task.configs if config.is_current
273
+ ]
274
+ for config in current_configs:
275
+ if config.config_type not in [
276
+ ManualTaskConfigurationType.access_privacy_request,
277
+ ManualTaskConfigurationType.erasure_privacy_request,
278
+ ]:
279
+ continue
280
+
281
+ for field in config.field_definitions:
282
+ # Create a scalar field for each manual task field
283
+ field_metadata = field.field_metadata or {}
284
+ data_categories = field_metadata.get("data_categories", [])
285
+
286
+ scalar_field = ScalarField(
287
+ name=field.field_key,
288
+ data_categories=data_categories,
289
+ )
290
+ fields.append(scalar_field)
344
291
 
345
292
  if fields: # Only create graph if there are fields
346
293
  # Create a synthetic Collection
fides/api/util/cache.py CHANGED
@@ -387,3 +387,8 @@ def get_queue_counts() -> Dict[str, int]:
387
387
  logger.critical(exception)
388
388
  queue_counts = {}
389
389
  return queue_counts
390
+
391
+
392
+ def get_all_masking_secret_keys(privacy_request_id: str) -> List[str]:
393
+ cache: FidesopsRedis = get_cache()
394
+ return cache.keys(f"id-{privacy_request_id}-masking-secret-*")