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