ethyca-fides 2.66.2rc0__py2.py3-none-any.whl → 2.67.0rc0__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 (326) hide show
  1. {ethyca_fides-2.66.2rc0.dist-info → ethyca_fides-2.67.0rc0.dist-info}/METADATA +1 -1
  2. {ethyca_fides-2.66.2rc0.dist-info → ethyca_fides-2.67.0rc0.dist-info}/RECORD +292 -279
  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/graph.py +13 -2
  17. fides/api/graph/traversal.py +126 -39
  18. fides/api/models/manual_task/__init__.py +2 -0
  19. fides/api/models/manual_task/conditional_dependency.py +144 -0
  20. fides/api/models/{manual_task.py → manual_task/manual_task.py} +10 -0
  21. fides/api/models/masking_secret.py +72 -0
  22. fides/api/models/policy.py +23 -0
  23. fides/api/models/privacy_request/execution_log.py +1 -0
  24. fides/api/models/privacy_request/privacy_request.py +31 -13
  25. fides/api/oauth/roles.py +2 -0
  26. fides/api/schemas/application_config.py +11 -1
  27. fides/api/schemas/masking/masking_secrets.py +1 -1
  28. fides/api/schemas/policy.py +1 -0
  29. fides/api/schemas/privacy_request.py +5 -0
  30. fides/api/service/connectors/base_connector.py +1 -0
  31. fides/api/service/connectors/bigquery_connector.py +67 -19
  32. fides/api/service/connectors/dynamodb_connector.py +2 -1
  33. fides/api/service/connectors/fides_connector.py +1 -0
  34. fides/api/service/connectors/http_connector.py +1 -0
  35. fides/api/service/connectors/manual_task_connector.py +1 -0
  36. fides/api/service/connectors/manual_webhook_connector.py +2 -1
  37. fides/api/service/connectors/mongodb_connector.py +1 -0
  38. fides/api/service/connectors/okta_connector.py +1 -0
  39. fides/api/service/connectors/query_configs/bigquery_query_config.py +91 -32
  40. fides/api/service/connectors/rds_mysql_connector.py +1 -0
  41. fides/api/service/connectors/rds_postgres_connector.py +1 -0
  42. fides/api/service/connectors/s3_connector.py +1 -0
  43. fides/api/service/connectors/saas_connector.py +1 -0
  44. fides/api/service/connectors/scylla_connector.py +1 -0
  45. fides/api/service/connectors/sql_connector.py +36 -4
  46. fides/api/service/connectors/website_connector.py +1 -0
  47. fides/api/service/privacy_request/dsr_package/templates/welcome.html +2 -2
  48. fides/api/service/privacy_request/request_runner_service.py +142 -53
  49. fides/api/service/privacy_request/request_service.py +1 -22
  50. fides/api/task/conditional_dependencies/__init__.py +0 -0
  51. fides/api/task/conditional_dependencies/evaluator.py +109 -0
  52. fides/api/task/conditional_dependencies/schemas.py +54 -0
  53. fides/api/task/create_request_tasks.py +1 -1
  54. fides/api/task/deprecated_graph_task.py +24 -6
  55. fides/api/task/execute_request_tasks.py +89 -12
  56. fides/api/task/filter_results.py +1 -1
  57. fides/api/task/graph_task.py +38 -3
  58. fides/api/task/manual/manual_task_address.py +46 -0
  59. fides/api/task/manual/manual_task_graph_task.py +118 -126
  60. fides/api/task/manual/manual_task_utils.py +52 -105
  61. fides/api/util/aws_util.py +5 -1
  62. fides/api/util/cache.py +5 -0
  63. fides/api/util/encryption/secrets_util.py +48 -18
  64. fides/common/api/scope_registry.py +3 -0
  65. fides/common/api/v1/urn_registry.py +1 -1
  66. fides/config/execution_settings.py +4 -0
  67. fides/config/utils.py +1 -0
  68. fides/service/privacy_request/privacy_request_service.py +6 -1
  69. fides/ui-build/static/admin/404.html +1 -1
  70. fides/ui-build/static/admin/_next/static/GKmhMPa_1gMto8JZO8ENy/_buildManifest.js +1 -0
  71. fides/ui-build/static/admin/_next/static/chunks/1316-2606e19807c08aa5.js +1 -0
  72. fides/ui-build/static/admin/_next/static/chunks/1467-8808ec8836e033f9.js +1 -0
  73. fides/ui-build/static/admin/_next/static/chunks/1817-b78b58ae3b75d75a.js +1 -0
  74. fides/ui-build/static/admin/_next/static/chunks/1975.7d4634a0e823a02b.js +1 -0
  75. fides/ui-build/static/admin/_next/static/chunks/{203-5a663f465ba26bb4.js → 203-cd78ea279cecba60.js} +1 -1
  76. fides/ui-build/static/admin/_next/static/chunks/2150-930ffaf2c4718edc.js +1 -0
  77. fides/ui-build/static/admin/_next/static/chunks/255-1bc0cbef7a59cdc6.js +1 -0
  78. fides/ui-build/static/admin/_next/static/chunks/{3450-0ba194991d0cca88.js → 3450-ca4ba70da999f264.js} +1 -1
  79. fides/ui-build/static/admin/_next/static/chunks/346-aa3b88efb85f2e28.js +1 -0
  80. fides/ui-build/static/admin/_next/static/chunks/3550-d04125c828d591a1.js +1 -0
  81. fides/ui-build/static/admin/_next/static/chunks/{3855-e172870d3e21b0dd.js → 3855-509ca7ac99b5eada.js} +1 -1
  82. fides/ui-build/static/admin/_next/static/chunks/{3872-46cebf7ec1b31a2b.js → 3872-0a0f0032ca39a93f.js} +1 -1
  83. fides/ui-build/static/admin/_next/static/chunks/409-ea70638a59296659.js +1 -0
  84. fides/ui-build/static/admin/_next/static/chunks/{4121-2bc09fc4ddbfe5cb.js → 4121-877e19d3fa078c7b.js} +1 -1
  85. fides/ui-build/static/admin/_next/static/chunks/{4230-60100f7ef3ddcde1.js → 4230-114e31621c19ea69.js} +1 -1
  86. fides/ui-build/static/admin/_next/static/chunks/4259.d1507e0db19cbed7.js +1 -0
  87. fides/ui-build/static/admin/_next/static/chunks/431-1db919f6569a4021.js +1 -0
  88. fides/ui-build/static/admin/_next/static/chunks/{4608-bbb7bf511a05c3c2.js → 4608-43acf39319177bee.js} +1 -1
  89. fides/ui-build/static/admin/_next/static/chunks/5163-e682273cd76a7d07.js +1 -0
  90. fides/ui-build/static/admin/_next/static/chunks/{5309-b2c4803370634ff8.js → 5309-ce5702b9faeaff55.js} +1 -1
  91. fides/ui-build/static/admin/_next/static/chunks/{905-ffdbd0b14167e8bd.js → 5596-4378b2927dae65b2.js} +3 -3
  92. fides/ui-build/static/admin/_next/static/chunks/5619-9b50cec521203989.js +1 -0
  93. fides/ui-build/static/admin/_next/static/chunks/{6084-7178ff6ea6822475.js → 6084-ddbad3149364725d.js} +1 -1
  94. fides/ui-build/static/admin/_next/static/chunks/6148-59a59d5c5925344f.js +1 -0
  95. fides/ui-build/static/admin/_next/static/chunks/6419-d0c00d661b01f8fa.js +1 -0
  96. fides/ui-build/static/admin/_next/static/chunks/{6662-507be5d46e5b719b.js → 6662-4392ba1e4c254ef7.js} +1 -1
  97. fides/ui-build/static/admin/_next/static/chunks/6780-fc7d9ddb1a03e7b3.js +1 -0
  98. fides/ui-build/static/admin/_next/static/chunks/{6853-2ad3e08fe6f9f5f2.js → 6853-d0190d2cca9dbde2.js} +1 -1
  99. fides/ui-build/static/admin/_next/static/chunks/{6882-6af16fef26c21e06.js → 6882-59ea739e3616ce83.js} +1 -1
  100. fides/ui-build/static/admin/_next/static/chunks/6954-9c4912fbce87c4df.js +1 -0
  101. fides/ui-build/static/admin/_next/static/chunks/{7476-281ee9a8286556f3.js → 7476-cc0d9a94ed7aad53.js} +1 -1
  102. fides/ui-build/static/admin/_next/static/chunks/{787-fb41002f797eb2df.js → 787-c57185ad89c4e288.js} +1 -1
  103. fides/ui-build/static/admin/_next/static/chunks/{79-7e87aff851423d4a.js → 79-2aab56be75e16187.js} +1 -1
  104. fides/ui-build/static/admin/_next/static/chunks/{796-329a5f823ec258a5.js → 796-3bdda2a7868464af.js} +1 -1
  105. fides/ui-build/static/admin/_next/static/chunks/8237-841439bef6682177.js +1 -0
  106. fides/ui-build/static/admin/_next/static/chunks/8765-f622a35b40a7ec63.js +1 -0
  107. fides/ui-build/static/admin/_next/static/chunks/{9046-5c4c22c375de25b1.js → 9046-04a8c092fef1cd83.js} +1 -1
  108. fides/ui-build/static/admin/_next/static/chunks/9187-7438242f0d380bb0.js +1 -0
  109. fides/ui-build/static/admin/_next/static/chunks/{9226-746771d47dff6266.js → 9226-2dcac54ab3fb94be.js} +1 -1
  110. fides/ui-build/static/admin/_next/static/chunks/9278-08cc704317fe535e.js +1 -0
  111. fides/ui-build/static/admin/_next/static/chunks/{9951-9b753ad7c3f51bdf.js → 9951-7c6639e5d062779e.js} +1 -1
  112. fides/ui-build/static/admin/_next/static/chunks/pages/{_app-39ccb07327c2c5d5.js → _app-4b5bff46158a19a3.js} +56 -56
  113. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{manual-98777246bec9dc2a.js → manual-2a655ff3a97f2492.js} +1 -1
  114. fides/ui-build/static/admin/_next/static/chunks/pages/{add-systems-a71c0aff4e0e6535.js → add-systems-0902f0bb4080643e.js} +1 -1
  115. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-1edf582ba3cd3bbb.js → [id]-f22ddd9b48a5c418.js} +1 -1
  116. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{new-06bb3b0bf097fcdb.js → new-e74cb5ea87f15b40.js} +1 -1
  117. fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-experience-685771e5f7196d87.js → privacy-experience-21f997c69fc3b4c2.js} +1 -1
  118. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-6ccedc70dc447089.js → [id]-da4124b7600a2a1d.js} +1 -1
  119. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-944bca1cc57985b5.js → new-a57d251c88ce68ae.js} +1 -1
  120. fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-notices-84f4bd14ce8673bc.js → privacy-notices-ad105181bc91209b.js} +1 -1
  121. fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-b0c4235fe6d0b0c8.js +1 -0
  122. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/{[resourceUrn]-11d52f1570759c4d.js → [resourceUrn]-aad6047a4604b945.js} +1 -1
  123. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{projects-32eac8bbd217615a.js → projects-29784a11fe0fbd0a.js} +1 -1
  124. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/{[resourceUrn]-b83afa5565d0c84e.js → [resourceUrn]-b6b98cea25dd94fa.js} +1 -1
  125. fides/ui-build/static/admin/_next/static/chunks/pages/{data-catalog-6f630d42ac9fb6b4.js → data-catalog-d5b01abcb76792ce.js} +1 -1
  126. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-7caea7bb58c1f153.js +1 -0
  127. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-a9a70856f7be1542.js +1 -0
  128. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{action-center-9ddb52ebb7ac4c71.js → action-center-1f0ea5c92ae9a2b4.js} +1 -1
  129. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{activity-9aa744d56cdacb0d.js → activity-ad6a84a6276f914c.js} +1 -1
  130. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-14bd7500362ff224.js → [resourceUrn]-f98dd251babb7e28.js} +1 -1
  131. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-9e7dfd5a6acc2e8f.js → discovery-56eb4c014f0d96a3.js} +1 -1
  132. fides/ui-build/static/admin/_next/static/chunks/pages/datamap-d23b3ae139f0428b.js +1 -0
  133. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/{[...subfieldNames]-c0d2bfd465df20e0.js → [...subfieldNames]-15301bd6bf7cf718.js} +1 -1
  134. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/{[collectionName]-28280a8a39a6e37c.js → [collectionName]-0fa72873e464f581.js} +1 -1
  135. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{new-82fb246d87e58ebd.js → new-0d50084fbdf9b84c.js} +1 -1
  136. fides/ui-build/static/admin/_next/static/chunks/pages/{dataset-20165c31ab1bc7cf.js → dataset-f3348d0a92543bab.js} +1 -1
  137. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{[id]-b4a6bcc87d126840.js → [id]-7d6027570d05c57f.js} +1 -1
  138. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{new-f95d7b0bbfc58f5a.js → new-8446418c7ad28f77.js} +1 -1
  139. fides/ui-build/static/admin/_next/static/chunks/pages/{fides-js-docs-5d8fd1af75f19e2f.js → fides-js-docs-1f4335dca5c09860.js} +1 -1
  140. fides/ui-build/static/admin/_next/static/chunks/pages/{index-1919aab9e5834b51.js → index-fbf9b845bb901238.js} +1 -1
  141. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/{[id]-0a58aee2d1e7fa01.js → [id]-f53fe1f2cbebda7c.js} +1 -1
  142. fides/ui-build/static/admin/_next/static/chunks/pages/{integrations-e2d5d7e2a5265e68.js → integrations-142abe3e3e3e5bf7.js} +1 -1
  143. fides/ui-build/static/admin/_next/static/chunks/pages/messaging-1bae386d8c190348.js +1 -0
  144. fides/ui-build/static/admin/_next/static/chunks/pages/poc/{table-migration-69ad86b7a8a9a115.js → table-migration-05616e2ae20ff4f8.js} +1 -1
  145. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-1b6b0d703cf59389.js +1 -0
  146. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-f1d818242d8550f8.js +1 -0
  147. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-d40a26bddb126c5c.js +1 -0
  148. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-ccd8d9e06cf2d278.js +1 -0
  149. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-fd1a67892056830a.js +1 -0
  150. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/{[purpose_id]-fc201657f4a782c7.js → [purpose_id]-e891d01ece59669e.js} +1 -1
  151. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{consent-c2d39cba8396ef3a.js → consent-f61b87e79367865b.js} +1 -1
  152. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{custom-fields-d992103cc55901ae.js → custom-fields-f8eea5d508c60c64.js} +1 -1
  153. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-023e1895552817de.js → locations-ed6a140b362c5baa.js} +1 -1
  154. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{organization-ac403c0886b20e20.js → organization-ff9a34264d48c35f.js} +1 -1
  155. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/{test-datasets-7a3396ac819c7904.js → test-datasets-a4b6d41ca679298b.js} +1 -1
  156. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-8314a819837f5b2a.js → [id]-c8f5fbaa83dd9945.js} +1 -1
  157. fides/ui-build/static/admin/_next/static/chunks/pages/{systems-21f423a7c417aa9d.js → systems-c05b49ddec1a1b4f.js} +1 -1
  158. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-df0d88716578e295.js +1 -0
  159. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/[id]-da68efc31998dc66.js +1 -0
  160. fides/ui-build/static/admin/_next/static/chunks/pages/{user-management-173ac3a1ed2b05a6.js → user-management-e98dfc7d4f2a4e16.js} +1 -1
  161. fides/ui-build/static/admin/_next/static/chunks/webpack-90e8ec1fc5c6455b.js +1 -0
  162. fides/ui-build/static/admin/_next/static/css/{5bfb2473e5701527.css → 23cf870196941c9a.css} +1 -1
  163. fides/ui-build/static/admin/_next/static/css/{94965f224bc991e9.css → 8bc1833f1fa53ff0.css} +1 -1
  164. fides/ui-build/static/admin/_next/static/css/d9924caa849931b3.css +1 -0
  165. fides/ui-build/static/admin/_next/static/css/dbcf63488933a4d5.css +29 -0
  166. fides/ui-build/static/admin/add-systems/manual.html +1 -1
  167. fides/ui-build/static/admin/add-systems/multiple.html +1 -1
  168. fides/ui-build/static/admin/add-systems.html +1 -1
  169. fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
  170. fides/ui-build/static/admin/consent/configure.html +1 -1
  171. fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
  172. fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
  173. fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
  174. fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
  175. fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
  176. fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
  177. fides/ui-build/static/admin/consent/properties.html +1 -1
  178. fides/ui-build/static/admin/consent/reporting.html +1 -1
  179. fides/ui-build/static/admin/consent.html +1 -1
  180. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
  181. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
  182. fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
  183. fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
  184. fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
  185. fides/ui-build/static/admin/data-catalog.html +1 -1
  186. fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/[systemId].html +1 -1
  187. fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +1 -1
  188. fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
  189. fides/ui-build/static/admin/data-discovery/activity.html +1 -1
  190. fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
  191. fides/ui-build/static/admin/data-discovery/detection.html +1 -1
  192. fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
  193. fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
  194. fides/ui-build/static/admin/datamap.html +1 -1
  195. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
  196. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
  197. fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
  198. fides/ui-build/static/admin/dataset/new.html +1 -1
  199. fides/ui-build/static/admin/dataset.html +1 -1
  200. fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
  201. fides/ui-build/static/admin/datastore-connection/new.html +1 -1
  202. fides/ui-build/static/admin/datastore-connection.html +1 -1
  203. fides/ui-build/static/admin/index.html +1 -1
  204. fides/ui-build/static/admin/integrations/[id].html +1 -1
  205. fides/ui-build/static/admin/integrations.html +1 -1
  206. fides/ui-build/static/admin/lib/fides-ext-gpp.js +1 -1
  207. fides/ui-build/static/admin/lib/fides-headless.js +1 -1
  208. fides/ui-build/static/admin/lib/fides-preview.js +1 -1
  209. fides/ui-build/static/admin/lib/fides-tcf.js +3 -3
  210. fides/ui-build/static/admin/lib/fides.js +3 -3
  211. fides/ui-build/static/admin/login/[provider].html +1 -1
  212. fides/ui-build/static/admin/login.html +1 -1
  213. fides/ui-build/static/admin/messaging/[id].html +1 -1
  214. fides/ui-build/static/admin/messaging/add-template.html +1 -1
  215. fides/ui-build/static/admin/messaging.html +1 -1
  216. fides/ui-build/static/admin/poc/ant-components.html +1 -1
  217. fides/ui-build/static/admin/poc/form-experiments/AntForm.html +1 -1
  218. fides/ui-build/static/admin/poc/form-experiments/FormikAntFormItem.html +1 -1
  219. fides/ui-build/static/admin/poc/form-experiments/FormikControlled.html +1 -1
  220. fides/ui-build/static/admin/poc/form-experiments/FormikField.html +1 -1
  221. fides/ui-build/static/admin/poc/form-experiments/FormikSpreadField.html +1 -1
  222. fides/ui-build/static/admin/poc/forms.html +1 -1
  223. fides/ui-build/static/admin/poc/table-migration.html +1 -1
  224. fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
  225. fides/ui-build/static/admin/privacy-requests/configure/messaging.html +1 -1
  226. fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
  227. fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
  228. fides/ui-build/static/admin/privacy-requests.html +1 -1
  229. fides/ui-build/static/admin/properties/[id].html +1 -1
  230. fides/ui-build/static/admin/properties/add-property.html +1 -1
  231. fides/ui-build/static/admin/properties.html +1 -1
  232. fides/ui-build/static/admin/reporting/datamap.html +1 -1
  233. fides/ui-build/static/admin/settings/about/alpha.html +1 -1
  234. fides/ui-build/static/admin/settings/about.html +1 -1
  235. fides/ui-build/static/admin/settings/consent/[configuration_id]/[purpose_id].html +1 -1
  236. fides/ui-build/static/admin/settings/consent.html +1 -1
  237. fides/ui-build/static/admin/settings/custom-fields.html +1 -1
  238. fides/ui-build/static/admin/settings/domain-records.html +1 -1
  239. fides/ui-build/static/admin/settings/domains.html +1 -1
  240. fides/ui-build/static/admin/settings/email-templates.html +1 -1
  241. fides/ui-build/static/admin/settings/locations.html +1 -1
  242. fides/ui-build/static/admin/settings/organization.html +1 -1
  243. fides/ui-build/static/admin/settings/regulations.html +1 -1
  244. fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
  245. fides/ui-build/static/admin/systems/configure/[id].html +1 -1
  246. fides/ui-build/static/admin/systems.html +1 -1
  247. fides/ui-build/static/admin/taxonomy.html +1 -1
  248. fides/ui-build/static/admin/user-management/new.html +1 -1
  249. fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
  250. fides/ui-build/static/admin/user-management.html +1 -1
  251. fides/ui-build/static/admin/_next/static/8108ANFxs99VY7KZ_Xev2/_buildManifest.js +0 -1
  252. fides/ui-build/static/admin/_next/static/chunks/1316-6cc72a45ebf7ff81.js +0 -1
  253. fides/ui-build/static/admin/_next/static/chunks/1807-3beab149351d5ded.js +0 -1
  254. fides/ui-build/static/admin/_next/static/chunks/1817-e601e737e3cc7a0e.js +0 -1
  255. fides/ui-build/static/admin/_next/static/chunks/255-7db55b0e3a0f9dea.js +0 -1
  256. fides/ui-build/static/admin/_next/static/chunks/2599-6c4d22e75028d8b6.js +0 -1
  257. fides/ui-build/static/admin/_next/static/chunks/2858-0b44609b6be7850b.js +0 -1
  258. fides/ui-build/static/admin/_next/static/chunks/2866-a73888c17a195cbe.js +0 -1
  259. fides/ui-build/static/admin/_next/static/chunks/3615-5e2d062d684b8fa1.js +0 -1
  260. fides/ui-build/static/admin/_next/static/chunks/409-a257e14acebcd73b.js +0 -1
  261. fides/ui-build/static/admin/_next/static/chunks/431-34f0b91c26f8d9ab.js +0 -1
  262. fides/ui-build/static/admin/_next/static/chunks/570-c99f07161bd339cd.js +0 -1
  263. fides/ui-build/static/admin/_next/static/chunks/6780-e3d40aa17a4bf2e9.js +0 -1
  264. fides/ui-build/static/admin/_next/static/chunks/6954-bb875d9ac89f6030.js +0 -1
  265. fides/ui-build/static/admin/_next/static/chunks/7062.fda15dcb7df85675.js +0 -1
  266. fides/ui-build/static/admin/_next/static/chunks/7c79804f.7a7112aece470725.js +0 -1
  267. fides/ui-build/static/admin/_next/static/chunks/9014-eeae6f581158e645.js +0 -1
  268. fides/ui-build/static/admin/_next/static/chunks/9278-9b1b5970f0702668.js +0 -1
  269. fides/ui-build/static/admin/_next/static/chunks/9392.f4520f66206d347d.js +0 -1
  270. fides/ui-build/static/admin/_next/static/chunks/ea076c0a.84423f606aef37cd.js +0 -1
  271. fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-afdbd4665657cfa1.js +0 -1
  272. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-2265ecb899d45fbc.js +0 -1
  273. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-5d522637871ac6c8.js +0 -1
  274. fides/ui-build/static/admin/_next/static/chunks/pages/datamap-7674b97d655c193b.js +0 -1
  275. fides/ui-build/static/admin/_next/static/chunks/pages/messaging-5094ffea13f32ed9.js +0 -1
  276. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-32600543eb7b584f.js +0 -1
  277. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-10ce53ea356f8bad.js +0 -1
  278. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-5501bbb129fee9c4.js +0 -1
  279. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-cbe4c8f9096b6543.js +0 -1
  280. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-e130c0197362e8f3.js +0 -1
  281. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-6387fcc8cce872eb.js +0 -1
  282. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/[id]-ff5738706da07801.js +0 -1
  283. fides/ui-build/static/admin/_next/static/chunks/webpack-ff0cd6bff75588da.js +0 -1
  284. fides/ui-build/static/admin/_next/static/css/2cadb5f62dcd7c2b.css +0 -1
  285. {ethyca_fides-2.66.2rc0.dist-info → ethyca_fides-2.67.0rc0.dist-info}/WHEEL +0 -0
  286. {ethyca_fides-2.66.2rc0.dist-info → ethyca_fides-2.67.0rc0.dist-info}/entry_points.txt +0 -0
  287. {ethyca_fides-2.66.2rc0.dist-info → ethyca_fides-2.67.0rc0.dist-info}/licenses/LICENSE +0 -0
  288. {ethyca_fides-2.66.2rc0.dist-info → ethyca_fides-2.67.0rc0.dist-info}/top_level.txt +0 -0
  289. /fides/ui-build/static/admin/_next/static/{8108ANFxs99VY7KZ_Xev2 → GKmhMPa_1gMto8JZO8ENy}/_ssgManifest.js +0 -0
  290. /fides/ui-build/static/admin/_next/static/chunks/{2921-455e6357b74d2f76.js → 2921-86f1547ac40a5cdf.js} +0 -0
  291. /fides/ui-build/static/admin/_next/static/chunks/{3923-6cc911dafccc5f63.js → 3923-13a6b4da2d51bf8f.js} +0 -0
  292. /fides/ui-build/static/admin/_next/static/chunks/{401-1b529d5800aa1f3a.js → 401-3cc1fee61494e3bd.js} +0 -0
  293. /fides/ui-build/static/admin/_next/static/chunks/{5574-b13021775a15bfd2.js → 5574-9312f97b637d9ee2.js} +0 -0
  294. /fides/ui-build/static/admin/_next/static/chunks/{7630-9aac73191ed5ed13.js → 7630-b1c93688013ef013.js} +0 -0
  295. /fides/ui-build/static/admin/_next/static/chunks/{9826-111aaee8bd8dbd09.js → 9826-3c578665c6d3b21d.js} +0 -0
  296. /fides/ui-build/static/admin/_next/static/chunks/pages/{404-aece2c920ea14514.js → 404-2d803dab6a00f353.js} +0 -0
  297. /fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{multiple-dc75dc6e37e52f05.js → multiple-8ff7f37913ad736a.js} +0 -0
  298. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-24d226b5a8de5c74.js → add-vendors-d00c9034cdeb0236.js} +0 -0
  299. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{configure-6a8ef51138ac926a.js → configure-0e1ca0f4c8e7f4da.js} +0 -0
  300. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{properties-6f86ab63a08a6528.js → properties-057cad65e7414a44.js} +0 -0
  301. /fides/ui-build/static/admin/_next/static/chunks/pages/{consent-73d3cbf68f7c3a31.js → consent-e17c56eec8d91371.js} +0 -0
  302. /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/{[projectUrn]-6ba9e160dae64695.js → [projectUrn]-80a6cc8e8573514a.js} +0 -0
  303. /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{resources-7648bbd4f6711e4d.js → resources-6c3714ee97a718c1.js} +0 -0
  304. /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-393e20924c83373e.js → [resourceUrn]-31e6c54794a9883e.js} +0 -0
  305. /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-8733807dad4bc96e.js → detection-2822a423a7ad0550.js} +0 -0
  306. /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{[datasetId]-006b695e5af5ef24.js → [datasetId]-a8e8b5f4ee7af86c.js} +0 -0
  307. /fides/ui-build/static/admin/_next/static/chunks/pages/{datastore-connection-c391c6fad56eec48.js → datastore-connection-0f29b47402292070.js} +0 -0
  308. /fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{[id]-53fecfb9dd6a1e0c.js → [id]-5627d0d0668077f9.js} +0 -0
  309. /fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{add-template-76b01cec5fde10a9.js → add-template-feca66ad5c5fe54a.js} +0 -0
  310. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{ant-components-5c08e8447c45ce44.js → ant-components-64a322d01aae5ca7.js} +0 -0
  311. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{AntForm-06ad5f34585480aa.js → AntForm-8bca16a7726e7eb2.js} +0 -0
  312. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikAntFormItem-6f071c2bc9446cb0.js → FormikAntFormItem-b0f246fc3b67ebf7.js} +0 -0
  313. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikControlled-efcc38c58991ac9e.js → FormikControlled-1a0852b090bfc392.js} +0 -0
  314. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikField-430ba5c979abfb7c.js → FormikField-11f3de1b45e36583.js} +0 -0
  315. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{forms-5c561880bf131afb.js → forms-1b73a1c2b6c6285f.js} +0 -0
  316. /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{configure-d888a69a3bbe040e.js → configure-e551a860ec727802.js} +0 -0
  317. /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-d3d8e3d7583ec635.js → [id]-dd99183f93763ae4.js} +0 -0
  318. /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-1af10ed303815d46.js → add-property-0bdbc1fcbf553b8f.js} +0 -0
  319. /fides/ui-build/static/admin/_next/static/chunks/pages/{properties-cebc0dc186be499a.js → properties-e959378bb32b6b73.js} +0 -0
  320. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/{alpha-5e1322de868d615e.js → alpha-8f98a4895e74725e.js} +0 -0
  321. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{about-241f95e372b65d0f.js → about-8155a35a62fdb5ae.js} +0 -0
  322. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-41242f805599feda.js → domain-records-51333dbd21cb37c8.js} +0 -0
  323. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domains-2e885f74c92f669c.js → domains-bde86e5f6c09da5a.js} +0 -0
  324. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{email-templates-ff112655ad5f41e5.js → email-templates-4f9a5cc8bea7725b.js} +0 -0
  325. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-86062a18e081a52a.js → regulations-102efd9199e87124.js} +0 -0
  326. /fides/ui-build/static/admin/_next/static/chunks/pages/user-management/{new-a2524414e968f862.js → new-bc4eb541906781e6.js} +0 -0
@@ -421,6 +421,7 @@ class GraphTask(ABC): # pylint: disable=too-many-instance-attributes
421
421
  action_type: ActionType,
422
422
  ex: Optional[BaseException] = None,
423
423
  success_override_msg: Optional[str] = None,
424
+ record_count: Optional[int] = None,
424
425
  ) -> None:
425
426
  """On completion activities"""
426
427
  if ex:
@@ -440,8 +441,23 @@ class GraphTask(ABC): # pylint: disable=too-many-instance-attributes
440
441
  mark_current_and_downstream_nodes_as_failed(request_task, db)
441
442
  else:
442
443
  logger.info("Ending {}, {}", self.resources.request.id, self.key)
444
+
445
+ # Build standardized success message with record count
446
+ base_message = (
447
+ str(success_override_msg) if success_override_msg else "success"
448
+ )
449
+ if record_count is not None:
450
+ if action_type == ActionType.access:
451
+ message = f"{base_message} - retrieved {record_count} records"
452
+ elif action_type == ActionType.erasure:
453
+ message = f"{base_message} - masked {record_count} records"
454
+ else:
455
+ message = f"{base_message} - processed {record_count} records"
456
+ else:
457
+ message = base_message
458
+
443
459
  self.update_status(
444
- str(success_override_msg) if success_override_msg else "success",
460
+ message,
445
461
  build_affected_field_logs(
446
462
  self.execution_node, self.resources.policy, action_type
447
463
  ),
@@ -637,7 +653,11 @@ class GraphTask(ABC): # pylint: disable=too-many-instance-attributes
637
653
  if messages:
638
654
  success_message = "\n".join(messages)
639
655
 
640
- self.log_end(ActionType.access, success_override_msg=success_message)
656
+ self.log_end(
657
+ ActionType.access,
658
+ success_override_msg=success_message,
659
+ record_count=len(filtered_output),
660
+ )
641
661
  return filtered_output
642
662
 
643
663
  @retry(action_type=ActionType.erasure, default_return=0)
@@ -645,9 +665,15 @@ class GraphTask(ABC): # pylint: disable=too-many-instance-attributes
645
665
  self,
646
666
  retrieved_data: List[Row],
647
667
  *erasure_prereqs: int, # TODO Remove when we stop support for DSR 2.0. DSR 3.0 enforces with downstream_tasks.
668
+ inputs: Optional[
669
+ List[List[Row]]
670
+ ] = None, # Upstream data from corresponding access task
648
671
  ) -> int:
649
672
  """Run erasure request"""
650
673
 
674
+ if inputs is None:
675
+ inputs = []
676
+
651
677
  # if there is no primary key specified in the graph node configuration
652
678
  # note this in the execution log and perform no erasures on this node
653
679
  if (
@@ -694,6 +720,10 @@ class GraphTask(ABC): # pylint: disable=too-many-instance-attributes
694
720
  )
695
721
  return 0
696
722
 
723
+ formatted_input_data: NodeInput = self.pre_process_input_data(
724
+ *inputs, group_dependent_fields=True
725
+ )
726
+
697
727
  # Use execution context to capture postprocessor messages
698
728
  with collect_execution_log_messages() as messages:
699
729
  output = self.connector.mask_data(
@@ -702,6 +732,7 @@ class GraphTask(ABC): # pylint: disable=too-many-instance-attributes
702
732
  self.resources.request,
703
733
  self.resources.privacy_request_task,
704
734
  retrieved_data,
735
+ formatted_input_data,
705
736
  )
706
737
 
707
738
  if self.request_task.id:
@@ -720,7 +751,11 @@ class GraphTask(ABC): # pylint: disable=too-many-instance-attributes
720
751
  if messages:
721
752
  success_message = "\n".join(messages)
722
753
 
723
- self.log_end(ActionType.erasure, success_override_msg=success_message)
754
+ self.log_end(
755
+ ActionType.erasure,
756
+ success_override_msg=success_message,
757
+ record_count=output,
758
+ )
724
759
  return output
725
760
 
726
761
  @retry(action_type=ActionType.consent, default_return=False)
@@ -0,0 +1,46 @@
1
+ from fides.api.graph.config import CollectionAddress
2
+
3
+
4
+ class ManualTaskAddress:
5
+ """Utility class for creating and parsing manual task addresses"""
6
+
7
+ MANUAL_DATA_COLLECTION = "manual_data"
8
+
9
+ @staticmethod
10
+ def create(connection_config_key: str) -> CollectionAddress:
11
+ """Create a CollectionAddress for manual data: {connection_key}:manual_data"""
12
+ return CollectionAddress(
13
+ dataset=connection_config_key,
14
+ collection=ManualTaskAddress.MANUAL_DATA_COLLECTION,
15
+ )
16
+
17
+ @staticmethod
18
+ def _is_manual_data_collection(collection_name: str) -> bool:
19
+ """Check if collection name represents manual task data"""
20
+ return collection_name == ManualTaskAddress.MANUAL_DATA_COLLECTION
21
+
22
+ @staticmethod
23
+ def is_manual_task_address(address: CollectionAddress) -> bool:
24
+ """Check if address represents manual task data"""
25
+ if isinstance(address, str):
26
+ # Handle string format "connection_key:collection_name"
27
+ _, _, collection_part = address.partition(":")
28
+ if not collection_part:
29
+ return False
30
+ return ManualTaskAddress._is_manual_data_collection(collection_part)
31
+
32
+ # Handle CollectionAddress object
33
+ return ManualTaskAddress._is_manual_data_collection(address.collection)
34
+
35
+ @staticmethod
36
+ def get_connection_key(address: CollectionAddress) -> str:
37
+ """Extract connection config key from manual task address"""
38
+ if not ManualTaskAddress.is_manual_task_address(address):
39
+ raise ValueError(f"Not a manual task address: {address}")
40
+
41
+ if isinstance(address, str):
42
+ # Handle string format "connection_key:collection_name"
43
+ return address.split(":")[0]
44
+
45
+ # Handle CollectionAddress object
46
+ return address.dataset
@@ -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
  )