ethyca-fides 2.63.3b0__py2.py3-none-any.whl → 2.64.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.
Files changed (271) hide show
  1. {ethyca_fides-2.63.3b0.dist-info → ethyca_fides-2.64.0rc0.dist-info}/METADATA +1 -1
  2. {ethyca_fides-2.63.3b0.dist-info → ethyca_fides-2.64.0rc0.dist-info}/RECORD +228 -225
  3. fides/_version.py +3 -3
  4. fides/api/alembic/migrations/versions/ba414a58ba90_create_manual_task_config_tables.py +121 -0
  5. fides/api/db/base.py +4 -0
  6. fides/api/models/attachment.py +1 -0
  7. fides/api/models/manual_tasks/__init__.py +6 -0
  8. fides/api/models/manual_tasks/manual_task.py +11 -1
  9. fides/api/models/manual_tasks/manual_task_config.py +136 -0
  10. fides/api/models/manual_tasks/manual_task_log.py +13 -9
  11. fides/api/schemas/manual_tasks/manual_task_config.py +311 -0
  12. fides/api/schemas/manual_tasks/manual_task_schemas.py +1 -1
  13. fides/api/schemas/manual_tasks/manual_task_status.py +1 -1
  14. fides/api/schemas/privacy_request.py +2 -0
  15. fides/api/util/cache.py +6 -3
  16. fides/config/redis_settings.py +105 -44
  17. fides/service/manual_tasks/manual_task_config_service.py +370 -0
  18. fides/service/manual_tasks/manual_task_service.py +231 -87
  19. fides/service/manual_tasks/utils.py +185 -0
  20. fides/ui-build/static/admin/404.html +1 -1
  21. fides/ui-build/static/admin/_next/static/chunks/1040-630c7f4284dc6f70.js +1 -0
  22. fides/ui-build/static/admin/_next/static/chunks/1316-6cc72a45ebf7ff81.js +1 -0
  23. fides/ui-build/static/admin/_next/static/chunks/2430-b480401d44c55416.js +1 -0
  24. fides/ui-build/static/admin/_next/static/chunks/2599-6c4d22e75028d8b6.js +1 -0
  25. fides/ui-build/static/admin/_next/static/chunks/3450-bdaeb35442d810b4.js +1 -0
  26. fides/ui-build/static/admin/_next/static/chunks/3855-0dec3e7d9e886550.js +1 -0
  27. fides/ui-build/static/admin/_next/static/chunks/401-fceaae662cfca5a5.js +1 -0
  28. fides/ui-build/static/admin/_next/static/chunks/409-037cfc3f096150f0.js +1 -0
  29. fides/ui-build/static/admin/_next/static/chunks/4230-1cdb7ea1be370ed3.js +1 -0
  30. fides/ui-build/static/admin/_next/static/chunks/431-f72599f01b98f07d.js +1 -0
  31. fides/ui-build/static/admin/_next/static/chunks/5309-4511df9708d5a63c.js +1 -0
  32. fides/ui-build/static/admin/_next/static/chunks/5574-3cd33b3a6c937899.js +1 -0
  33. fides/ui-build/static/admin/_next/static/chunks/6662-cb11881dcaabe5e2.js +1 -0
  34. fides/ui-build/static/admin/_next/static/chunks/6882-3cc73d407a088d7d.js +1 -0
  35. fides/ui-build/static/admin/_next/static/chunks/699-8ca44b0de9fa20f0.js +1 -0
  36. fides/ui-build/static/admin/_next/static/chunks/9046-fdf53cc7e926a8c1.js +1 -0
  37. fides/ui-build/static/admin/_next/static/chunks/{905-5fe5124abfb5c542.js → 905-742074a074be1055.js} +1 -1
  38. fides/ui-build/static/admin/_next/static/chunks/9226-ba6587e46ec7659a.js +1 -0
  39. fides/ui-build/static/admin/_next/static/chunks/9767-e49b065d03ce4e80.js +1 -0
  40. fides/ui-build/static/admin/_next/static/chunks/9951-f9ab5cac7e2c05ab.js +1 -0
  41. fides/ui-build/static/admin/_next/static/chunks/pages/{_app-0e0fdbcc0ec1c76b.js → _app-8ec6e466f3373ac0.js} +6 -6
  42. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{manual-3065022f370ec055.js → manual-0a5f2310ce6b1059.js} +1 -1
  43. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/{[resourceUrn]-18e3faf7963962e4.js → [resourceUrn]-c623d6f1a61c8ea9.js} +1 -1
  44. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-cfac259a30641e68.js +1 -0
  45. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/{[resourceUrn]-7320524a47104798.js → [resourceUrn]-57bd5cdf784f059f.js} +1 -1
  46. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-7b5aec33da578745.js +1 -0
  47. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-c948f93c833d4358.js +1 -0
  48. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-333f53caab751428.js +1 -0
  49. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{action-center-18c144223277bc2e.js → action-center-27205f8457a1ecb0.js} +1 -1
  50. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-20a1043f6a06198f.js +1 -0
  51. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-4c526db0c30c488a.js → [resourceUrn]-06edce289876dea1.js} +1 -1
  52. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-6f27dbb7c8edc69d.js → detection-faf326a6200637d0.js} +1 -1
  53. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-562d2b8ae90dd1f0.js → [resourceUrn]-64acf269256ee74f.js} +1 -1
  54. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-fe7f51502eda57c9.js → discovery-8c3e4be6d36da66d.js} +1 -1
  55. fides/ui-build/static/admin/_next/static/chunks/pages/{datamap-9af01b6cf4cbe8af.js → datamap-fb50de22f83edd4a.js} +1 -1
  56. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/[...subfieldNames]-41ab27c4195cfa93.js +1 -0
  57. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]-6e2caba24b3e78c2.js +1 -0
  58. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-904d43e31157aa55.js +1 -0
  59. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-d4e31a1c4a58800e.js +1 -0
  60. fides/ui-build/static/admin/_next/static/chunks/pages/dataset-8f7d16bc5e9229c8.js +1 -0
  61. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{[id]-18ff06fc09c22c33.js → [id]-4a33dd0371dbaebc.js} +1 -1
  62. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{new-979eff6888e42b6b.js → new-e88509346b2d2851.js} +1 -1
  63. fides/ui-build/static/admin/_next/static/chunks/pages/{fides-js-docs-80b241bf6cddb72e.js → fides-js-docs-5d8fd1af75f19e2f.js} +1 -1
  64. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-fdc2964fa7d1d8fd.js +1 -0
  65. fides/ui-build/static/admin/_next/static/chunks/pages/integrations-adc286ff254e7f41.js +1 -0
  66. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-4cdbbb8cd1d8698e.js +1 -0
  67. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-d0e350d2a2667883.js +1 -0
  68. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-7796fbf458f8f159.js +1 -0
  69. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-6f866bc799a5f67f.js +1 -0
  70. fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-24108f615ff5e1e7.js +1 -0
  71. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-fef247a87baeb080.js +1 -0
  72. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-2b540203a2d7b59d.js → [id]-6eb886e7b7e6785b.js} +1 -1
  73. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-18534d2a79a3850b.js +1 -0
  74. fides/ui-build/static/admin/_next/static/chunks/webpack-0a61b5bd21a41fe6.js +1 -0
  75. fides/ui-build/static/admin/_next/static/css/c693338e3bc8dcc6.css +1 -0
  76. fides/ui-build/static/admin/_next/static/lDN8BtGGiw3b60__SDnAa/_buildManifest.js +1 -0
  77. fides/ui-build/static/admin/add-systems/manual.html +1 -1
  78. fides/ui-build/static/admin/add-systems/multiple.html +1 -1
  79. fides/ui-build/static/admin/add-systems.html +1 -1
  80. fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
  81. fides/ui-build/static/admin/consent/configure.html +1 -1
  82. fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
  83. fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
  84. fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
  85. fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
  86. fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
  87. fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
  88. fides/ui-build/static/admin/consent/properties.html +1 -1
  89. fides/ui-build/static/admin/consent/reporting.html +1 -1
  90. fides/ui-build/static/admin/consent.html +1 -1
  91. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
  92. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
  93. fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
  94. fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
  95. fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
  96. fides/ui-build/static/admin/data-catalog.html +1 -1
  97. fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/[systemId].html +1 -1
  98. fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +1 -1
  99. fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
  100. fides/ui-build/static/admin/data-discovery/activity.html +1 -1
  101. fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
  102. fides/ui-build/static/admin/data-discovery/detection.html +1 -1
  103. fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
  104. fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
  105. fides/ui-build/static/admin/datamap.html +1 -1
  106. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
  107. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
  108. fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
  109. fides/ui-build/static/admin/dataset/new.html +1 -1
  110. fides/ui-build/static/admin/dataset.html +1 -1
  111. fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
  112. fides/ui-build/static/admin/datastore-connection/new.html +1 -1
  113. fides/ui-build/static/admin/datastore-connection.html +1 -1
  114. fides/ui-build/static/admin/index.html +1 -1
  115. fides/ui-build/static/admin/integrations/[id].html +1 -1
  116. fides/ui-build/static/admin/integrations.html +1 -1
  117. fides/ui-build/static/admin/lib/fides-ext-gpp.js +1 -1
  118. fides/ui-build/static/admin/lib/fides-headless.js +1 -1
  119. fides/ui-build/static/admin/lib/fides-preview.js +1 -1
  120. fides/ui-build/static/admin/lib/fides-tcf.js +2 -2
  121. fides/ui-build/static/admin/lib/fides.js +2 -2
  122. fides/ui-build/static/admin/login/[provider].html +1 -1
  123. fides/ui-build/static/admin/login.html +1 -1
  124. fides/ui-build/static/admin/messaging/[id].html +1 -1
  125. fides/ui-build/static/admin/messaging/add-template.html +1 -1
  126. fides/ui-build/static/admin/messaging.html +1 -1
  127. fides/ui-build/static/admin/poc/ant-components.html +1 -1
  128. fides/ui-build/static/admin/poc/form-experiments/AntForm.html +1 -1
  129. fides/ui-build/static/admin/poc/form-experiments/FormikAntFormItem.html +1 -1
  130. fides/ui-build/static/admin/poc/form-experiments/FormikControlled.html +1 -1
  131. fides/ui-build/static/admin/poc/form-experiments/FormikField.html +1 -1
  132. fides/ui-build/static/admin/poc/form-experiments/FormikSpreadField.html +1 -1
  133. fides/ui-build/static/admin/poc/forms.html +1 -1
  134. fides/ui-build/static/admin/poc/table-migration.html +1 -1
  135. fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
  136. fides/ui-build/static/admin/privacy-requests/configure/messaging.html +1 -1
  137. fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
  138. fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
  139. fides/ui-build/static/admin/privacy-requests.html +1 -1
  140. fides/ui-build/static/admin/properties/[id].html +1 -1
  141. fides/ui-build/static/admin/properties/add-property.html +1 -1
  142. fides/ui-build/static/admin/properties.html +1 -1
  143. fides/ui-build/static/admin/reporting/datamap.html +1 -1
  144. fides/ui-build/static/admin/settings/about/alpha.html +1 -1
  145. fides/ui-build/static/admin/settings/about.html +1 -1
  146. fides/ui-build/static/admin/settings/consent/[configuration_id]/[purpose_id].html +1 -1
  147. fides/ui-build/static/admin/settings/consent.html +1 -1
  148. fides/ui-build/static/admin/settings/custom-fields.html +1 -1
  149. fides/ui-build/static/admin/settings/domain-records.html +1 -1
  150. fides/ui-build/static/admin/settings/domains.html +1 -1
  151. fides/ui-build/static/admin/settings/email-templates.html +1 -1
  152. fides/ui-build/static/admin/settings/locations.html +1 -1
  153. fides/ui-build/static/admin/settings/organization.html +1 -1
  154. fides/ui-build/static/admin/settings/regulations.html +1 -1
  155. fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
  156. fides/ui-build/static/admin/systems/configure/[id].html +1 -1
  157. fides/ui-build/static/admin/systems.html +1 -1
  158. fides/ui-build/static/admin/taxonomy.html +1 -1
  159. fides/ui-build/static/admin/user-management/new.html +1 -1
  160. fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
  161. fides/ui-build/static/admin/user-management.html +1 -1
  162. fides/ui-build/static/admin/_next/static/0S8UTwc7FKVdi3Eb4LgFK/_buildManifest.js +0 -1
  163. fides/ui-build/static/admin/_next/static/chunks/1099-f2199d5b88dd98b4.js +0 -1
  164. fides/ui-build/static/admin/_next/static/chunks/155-8ad794121fef6281.js +0 -1
  165. fides/ui-build/static/admin/_next/static/chunks/1904-e33cb75edb93d3d3.js +0 -1
  166. fides/ui-build/static/admin/_next/static/chunks/2310-efaa2a52fc487db4.js +0 -1
  167. fides/ui-build/static/admin/_next/static/chunks/3119-9be74ade1504a7e7.js +0 -1
  168. fides/ui-build/static/admin/_next/static/chunks/401-710009c2a7408818.js +0 -1
  169. fides/ui-build/static/admin/_next/static/chunks/4132-76ca1bcf79bf1d77.js +0 -1
  170. fides/ui-build/static/admin/_next/static/chunks/5258-8a1f7feddee7a960.js +0 -1
  171. fides/ui-build/static/admin/_next/static/chunks/5404-a8a82985736363f4.js +0 -1
  172. fides/ui-build/static/admin/_next/static/chunks/5487-483a111405f678e0.js +0 -1
  173. fides/ui-build/static/admin/_next/static/chunks/5683-7144f557d701406c.js +0 -1
  174. fides/ui-build/static/admin/_next/static/chunks/6202-86a62d94744e2c18.js +0 -1
  175. fides/ui-build/static/admin/_next/static/chunks/641-7e4eef3222cbda70.js +0 -1
  176. fides/ui-build/static/admin/_next/static/chunks/7980-3da0fe6938b0b758.js +0 -1
  177. fides/ui-build/static/admin/_next/static/chunks/8032-4b8bda7166eff954.js +0 -1
  178. fides/ui-build/static/admin/_next/static/chunks/8499-a65187ae77b7307b.js +0 -1
  179. fides/ui-build/static/admin/_next/static/chunks/8702-d1c8296f9f6afc10.js +0 -1
  180. fides/ui-build/static/admin/_next/static/chunks/9187-851756440f79cd75.js +0 -1
  181. fides/ui-build/static/admin/_next/static/chunks/9327-eb3b84680abcc660.js +0 -1
  182. fides/ui-build/static/admin/_next/static/chunks/9494-04a0483ed0ddad7c.js +0 -1
  183. fides/ui-build/static/admin/_next/static/chunks/9767-a3ed98edff04e6ed.js +0 -1
  184. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-b02050eb3b7113d4.js +0 -1
  185. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-ff211c7a968bda47.js +0 -1
  186. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-7f7435f28861ee78.js +0 -1
  187. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-ec4b981fd9cff542.js +0 -1
  188. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-e18f14b8d598e942.js +0 -1
  189. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/[...subfieldNames]-1987ef0d3c687aaa.js +0 -1
  190. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]-979828f48148b37c.js +0 -1
  191. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-e85c3537d3aade4a.js +0 -1
  192. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-6d44abbe7d454435.js +0 -1
  193. fides/ui-build/static/admin/_next/static/chunks/pages/dataset-42f276660c107e1c.js +0 -1
  194. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-63361d914d70d647.js +0 -1
  195. fides/ui-build/static/admin/_next/static/chunks/pages/integrations-fd73f276dad7a06c.js +0 -1
  196. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-f85f92726a61a668.js +0 -1
  197. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-e090903a572cba68.js +0 -1
  198. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-f0c8e4eced9f5cc5.js +0 -1
  199. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-f7a271ee53cb4e51.js +0 -1
  200. fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-dd903f6e03c4ee4e.js +0 -1
  201. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-493dc9b4595c9fb4.js +0 -1
  202. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-6d790458dd21dde7.js +0 -1
  203. fides/ui-build/static/admin/_next/static/chunks/webpack-abfd03ce7f1e55ac.js +0 -1
  204. fides/ui-build/static/admin/_next/static/css/c3377f99bf988d68.css +0 -1
  205. {ethyca_fides-2.63.3b0.dist-info → ethyca_fides-2.64.0rc0.dist-info}/WHEEL +0 -0
  206. {ethyca_fides-2.63.3b0.dist-info → ethyca_fides-2.64.0rc0.dist-info}/entry_points.txt +0 -0
  207. {ethyca_fides-2.63.3b0.dist-info → ethyca_fides-2.64.0rc0.dist-info}/licenses/LICENSE +0 -0
  208. {ethyca_fides-2.63.3b0.dist-info → ethyca_fides-2.64.0rc0.dist-info}/top_level.txt +0 -0
  209. /fides/ui-build/static/admin/_next/static/chunks/{1100-d617215143d70d3d.js → 1100-d43cb04522a6505c.js} +0 -0
  210. /fides/ui-build/static/admin/_next/static/chunks/{1817-ddfdd6ed9529bba6.js → 1817-b4688ba5042ec687.js} +0 -0
  211. /fides/ui-build/static/admin/_next/static/chunks/{2921-19664dd93e2bf1ea.js → 2921-aabf41bf3d7573f9.js} +0 -0
  212. /fides/ui-build/static/admin/_next/static/chunks/{3505-f6d55694ca5c9816.js → 3505-a79256cd851dfab4.js} +0 -0
  213. /fides/ui-build/static/admin/_next/static/chunks/{3513-656df06b45fedba3.js → 3513-8677ee280eaef0da.js} +0 -0
  214. /fides/ui-build/static/admin/_next/static/chunks/{3872-09df90521f7db611.js → 3872-ffa16c2df7ef0ab6.js} +0 -0
  215. /fides/ui-build/static/admin/_next/static/chunks/{3923-3d80020d02819c33.js → 3923-5d580fbb1dd6ae01.js} +0 -0
  216. /fides/ui-build/static/admin/_next/static/chunks/{4060-4e196835f56cc326.js → 4060-71cd041e5a57ca5a.js} +0 -0
  217. /fides/ui-build/static/admin/_next/static/chunks/{4121-80ac9bcd08f9cd7a.js → 4121-78a76e980acbd539.js} +0 -0
  218. /fides/ui-build/static/admin/_next/static/chunks/{4481-be144b50994f5135.js → 4481-f597a7cf03f8c9e1.js} +0 -0
  219. /fides/ui-build/static/admin/_next/static/chunks/{6277-0b1e3d23e97f5e19.js → 6277-3fb4c7fc790a6d20.js} +0 -0
  220. /fides/ui-build/static/admin/_next/static/chunks/{6853-d9c6c55d8562bc9b.js → 6853-a4097260e402980e.js} +0 -0
  221. /fides/ui-build/static/admin/_next/static/chunks/{69-a4d64cabe750b286.js → 69-6889d6674c95e7b5.js} +0 -0
  222. /fides/ui-build/static/admin/_next/static/chunks/{6954-8ed05ffdbf2ec086.js → 6954-13a25cef3a8fdd76.js} +0 -0
  223. /fides/ui-build/static/admin/_next/static/chunks/{7553-77c9715868d6ad13.js → 7553-a95939c32d54b5b7.js} +0 -0
  224. /fides/ui-build/static/admin/_next/static/chunks/{79-6c977013b6bedc23.js → 79-5670e31eb65d0a53.js} +0 -0
  225. /fides/ui-build/static/admin/_next/static/chunks/{796-1d77aa88b776ee4e.js → 796-9a6b13c838e25538.js} +0 -0
  226. /fides/ui-build/static/admin/_next/static/chunks/{8433-88fd946149dd1f27.js → 8433-adb1fcb29d82f1b7.js} +0 -0
  227. /fides/ui-build/static/admin/_next/static/chunks/pages/{404-c50dccc133b332a9.js → 404-ac2f0844e5c4b4cd.js} +0 -0
  228. /fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{multiple-357ef3b269c576bb.js → multiple-00cb904825aad7e3.js} +0 -0
  229. /fides/ui-build/static/admin/_next/static/chunks/pages/{add-systems-e8ae218a9d124ba7.js → add-systems-587e21d14e0a5196.js} +0 -0
  230. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-488507bb244cce9d.js → add-vendors-fa7305b88c1afd20.js} +0 -0
  231. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{configure-6f0b46ac2b112bfe.js → configure-f140ec9d8e8a0f7a.js} +0 -0
  232. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-5024b4ab40ba024c.js → [id]-0edb7c92518e7d21.js} +0 -0
  233. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-experience-2b62e5facfc51808.js → privacy-experience-d8d926f0735a2546.js} +0 -0
  234. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-71791459da78e35d.js → [id]-5c949f2e3cef2398.js} +0 -0
  235. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-26a7d52615b1ebb8.js → new-130155cfb4a0bcc7.js} +0 -0
  236. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-notices-25836dd5142f37e8.js → privacy-notices-1135ad8924d32c36.js} +0 -0
  237. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{properties-3a9021850242c78f.js → properties-776855e370414beb.js} +0 -0
  238. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{reporting-9a5d3cc5cbb4ef27.js → reporting-21c23f75ff1135d9.js} +0 -0
  239. /fides/ui-build/static/admin/_next/static/chunks/pages/{consent-9e21184279f8e126.js → consent-4d5ea70a77df1bb8.js} +0 -0
  240. /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/{[projectUrn]-64cea013d41e348a.js → [projectUrn]-030ee304cbe5e530.js} +0 -0
  241. /fides/ui-build/static/admin/_next/static/chunks/pages/{datastore-connection-343a3830b2d4cf22.js → datastore-connection-8f9b8890018e1ea5.js} +0 -0
  242. /fides/ui-build/static/admin/_next/static/chunks/pages/{index-737b0c430bf2f7a0.js → index-1adb6bcb71701ac2.js} +0 -0
  243. /fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{[id]-91e865a65a88d1a4.js → [id]-9b4d1d61c7c97509.js} +0 -0
  244. /fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{add-template-529c7e09b073edd2.js → add-template-f8fd4795e260887c.js} +0 -0
  245. /fides/ui-build/static/admin/_next/static/chunks/pages/{messaging-6226faba9595da71.js → messaging-aa744ae8b61e5ff2.js} +0 -0
  246. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{ant-components-0f7d4390e01f4ffb.js → ant-components-3407158757fb3627.js} +0 -0
  247. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{AntForm-a4e470f75a5553f8.js → AntForm-47e947c02ae90fd0.js} +0 -0
  248. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikAntFormItem-d814c1c56b4b04d8.js → FormikAntFormItem-24f9a44512ce8827.js} +0 -0
  249. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikControlled-0f68f2be09df2c76.js → FormikControlled-e567a69f8c37fb9a.js} +0 -0
  250. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikField-6b63d5c992466891.js → FormikField-35a33f9c7def2220.js} +0 -0
  251. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{forms-88eb9b98e8e4b426.js → forms-780e18dde8e38099.js} +0 -0
  252. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{table-migration-a3da91fd04eec8f5.js → table-migration-7a17dffa515e5560.js} +0 -0
  253. /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{[id]-b2ea863afce1d7f0.js → [id]-91dd0039cc2b70bc.js} +0 -0
  254. /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/{messaging-0831dfaa65ce0d50.js → messaging-b01cbbaac34dadbc.js} +0 -0
  255. /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/{storage-709676f00a491bca.js → storage-a15410de7f1d0f84.js} +0 -0
  256. /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{configure-0eac9951504b46a7.js → configure-1a1aa83a3f88844c.js} +0 -0
  257. /fides/ui-build/static/admin/_next/static/chunks/pages/{privacy-requests-88e20023c30113df.js → privacy-requests-c4e1b69fb5bab61a.js} +0 -0
  258. /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-3acc3107e9a21260.js → [id]-19737d4f21aadbee.js} +0 -0
  259. /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-2bf13ee02d8d5ab9.js → add-property-9ccb295110feee20.js} +0 -0
  260. /fides/ui-build/static/admin/_next/static/chunks/pages/{properties-822eac07220f55f8.js → properties-3a1037a2e036212a.js} +0 -0
  261. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/{alpha-88999260f855b448.js → alpha-965cc21889b25e44.js} +0 -0
  262. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{about-928b0b69e05fd430.js → about-0e1c381d488a7ada.js} +0 -0
  263. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-611980eee1ce9c8a.js → domain-records-0b44b2b224077dcd.js} +0 -0
  264. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domains-382cb6df12684bf8.js → domains-5d00e1155bd11178.js} +0 -0
  265. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{email-templates-5d664f2a0f11b626.js → email-templates-d2cdbe770683e9df.js} +0 -0
  266. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-ba569d22e1e3f6df.js → locations-811dadb489f23d7d.js} +0 -0
  267. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-fae8ecf7878bad2d.js → regulations-54f142bc3e4c95ba.js} +0 -0
  268. /fides/ui-build/static/admin/_next/static/chunks/pages/{systems-a278608ba0ddc66c.js → systems-7b71274334c559a4.js} +0 -0
  269. /fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/{[id]-eb30c9230a9ce9cc.js → [id]-75d41fde668b9025.js} +0 -0
  270. /fides/ui-build/static/admin/_next/static/chunks/pages/{user-management-381146aa81e3ffea.js → user-management-dd43755b687c09a7.js} +0 -0
  271. /fides/ui-build/static/admin/_next/static/{0S8UTwc7FKVdi3Eb4LgFK → lDN8BtGGiw3b60__SDnAa}/_ssgManifest.js +0 -0
@@ -0,0 +1,311 @@
1
+ from datetime import datetime
2
+ from enum import Enum
3
+ from typing import TYPE_CHECKING, Annotated, Literal, Optional, Union
4
+
5
+ from pydantic import ConfigDict, Field, ValidationInfo, field_validator, model_validator
6
+
7
+ from fides.api.schemas.base_class import FidesSchema
8
+
9
+ if TYPE_CHECKING: # pragma: no cover
10
+ from fides.api.models.manual_tasks.manual_task import ManualTask # pragma: no cover
11
+
12
+
13
+ class ManualTaskConfigurationType(str, Enum):
14
+ """Enum for manual task configuration types."""
15
+
16
+ access_privacy_request = "access_privacy_request"
17
+ erasure_privacy_request = "erasure_privacy_request"
18
+ # Add more configuration types as needed
19
+
20
+
21
+ class ManualTaskFieldType(str, Enum):
22
+ """Enum for manual task field types."""
23
+
24
+ text = "text" # Key-value pairs
25
+ checkbox = "checkbox" # Boolean value
26
+ attachment = "attachment" # File upload
27
+ # Add more field types as needed
28
+
29
+
30
+ class ManualTaskFieldMetadata(FidesSchema):
31
+ """Base schema for manual task field metadata."""
32
+
33
+ model_config = ConfigDict(extra="allow")
34
+
35
+ label: Annotated[str, Field(description="Display label for the field")]
36
+ required: Annotated[
37
+ bool, Field(default=False, description="Whether the field is required")
38
+ ]
39
+ help_text: Annotated[
40
+ Optional[str],
41
+ Field(default=None, description="Help text to display with the field"),
42
+ ]
43
+ data_uses: Annotated[
44
+ Optional[list[str]],
45
+ Field(
46
+ default=None,
47
+ description="List of data uses associated with this field",
48
+ ),
49
+ ]
50
+
51
+
52
+ class ManualTaskTextFieldMetadata(ManualTaskFieldMetadata):
53
+ """Schema text field metadata."""
54
+
55
+ placeholder: Annotated[
56
+ Optional[str], Field(default=None, description="Placeholder text for the field")
57
+ ]
58
+ default_value: Annotated[
59
+ Optional[str], Field(default=None, description="Default value for the field")
60
+ ]
61
+ max_length: Annotated[
62
+ Optional[int], Field(default=None, description="Maximum length for text fields")
63
+ ]
64
+ min_length: Annotated[
65
+ Optional[int], Field(default=None, description="Minimum length for text fields")
66
+ ]
67
+ pattern: Annotated[
68
+ Optional[str],
69
+ Field(
70
+ default=None,
71
+ description=(
72
+ "Regex pattern for validation, for example if the field is an email address, "
73
+ r"you could use: ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
74
+ ),
75
+ ),
76
+ ]
77
+
78
+ @field_validator("min_length", "max_length")
79
+ @classmethod
80
+ def validate_lengths(cls, v: Optional[int], info: ValidationInfo) -> Optional[int]:
81
+ """Validate that min_length is not greater than max_length."""
82
+ if v is None:
83
+ return v
84
+
85
+ if info.field_name == "min_length":
86
+ max_length = info.data.get("max_length")
87
+ if max_length is not None and v > max_length:
88
+ raise ValueError("min_length cannot be greater than max_length")
89
+ elif info.field_name == "max_length":
90
+ min_length = info.data.get("min_length")
91
+ if min_length is not None and v < min_length:
92
+ raise ValueError("min_length cannot be greater than max_length")
93
+
94
+ return v
95
+
96
+
97
+ class ManualTaskCheckboxFieldMetadata(ManualTaskFieldMetadata):
98
+ """Schema for checkbox field metadata."""
99
+
100
+ default_value: Annotated[
101
+ Optional[bool],
102
+ Field(default=False, description="Default value for the checkbox"),
103
+ ]
104
+ label_true: Annotated[
105
+ Optional[str], Field(default=None, description="Label for checked state")
106
+ ]
107
+ label_false: Annotated[
108
+ Optional[str], Field(default=None, description="Label for unchecked state")
109
+ ]
110
+
111
+
112
+ class ManualTaskAttachmentFieldMetadata(ManualTaskFieldMetadata):
113
+ """Schema for attachment field metadata."""
114
+
115
+ file_types: Annotated[
116
+ list[str], Field(description="Allowed file types for upload fields")
117
+ ]
118
+ max_file_size: Annotated[
119
+ int, Field(description="Maximum file size in bytes for upload fields")
120
+ ]
121
+ multiple: Annotated[
122
+ bool, Field(default=False, description="Whether multiple files can be uploaded")
123
+ ]
124
+ max_files: Annotated[
125
+ Optional[int],
126
+ Field(
127
+ default=None,
128
+ description="Maximum number of files allowed when multiple is true",
129
+ ),
130
+ ]
131
+ require_attachment_id: Annotated[
132
+ bool,
133
+ Field(
134
+ default=True,
135
+ description="Whether an attachment ID is required for this field",
136
+ ),
137
+ ]
138
+ attachment_ids: Annotated[
139
+ Optional[list[str]],
140
+ Field(
141
+ default=None,
142
+ description="List of attachment IDs associated with this field",
143
+ ),
144
+ ]
145
+
146
+ @model_validator(mode="after")
147
+ def validate_multiple_max_files(self) -> "ManualTaskAttachmentFieldMetadata":
148
+ """Validate that max_files is set when multiple is True."""
149
+ if self.multiple and self.max_files is None:
150
+ raise ValueError("max_files must be set when multiple is True")
151
+ return self
152
+
153
+
154
+ class ManualTaskFieldBase(FidesSchema):
155
+ """Base schema for all field definitions."""
156
+
157
+ model_config = ConfigDict(extra="allow")
158
+
159
+ field_key: Annotated[
160
+ str, Field(description="Unique key for the field", min_length=1)
161
+ ]
162
+ field_type: Annotated[ManualTaskFieldType, Field(description="Type of the field")]
163
+ field_metadata: Annotated[
164
+ ManualTaskFieldMetadata, Field(description="Field metadata and configuration")
165
+ ]
166
+
167
+ @classmethod
168
+ def get_field_model_for_type(
169
+ cls, field_type: Union[str, ManualTaskFieldType]
170
+ ) -> type["ManualTaskFieldBase"]:
171
+ """Get the appropriate field model class for a given field type.
172
+
173
+ Args:
174
+ field_type: The field type as a string or ManualTaskFieldType enum value
175
+
176
+ Returns:
177
+ The appropriate field model class
178
+
179
+ Raises:
180
+ ValueError: If the field type is not recognized
181
+ """
182
+ # Handle non-string/non-enum types
183
+ if not isinstance(field_type, (str, ManualTaskFieldType)):
184
+ raise ValueError(
185
+ f"Invalid field type: expected string or ManualTaskFieldType, got {type(field_type).__name__}"
186
+ )
187
+
188
+ # Convert string to enum if needed
189
+ if isinstance(field_type, str):
190
+ try:
191
+ field_type = ManualTaskFieldType(field_type)
192
+ except ValueError:
193
+ raise ValueError(
194
+ f"Invalid field type: '{field_type}' is not a valid ManualTaskFieldType"
195
+ )
196
+
197
+ # Map field types to their model classes
198
+ field_type_to_model = {
199
+ ManualTaskFieldType.text: ManualTaskTextField,
200
+ ManualTaskFieldType.checkbox: ManualTaskCheckboxField,
201
+ ManualTaskFieldType.attachment: ManualTaskAttachmentField,
202
+ }
203
+
204
+ model_class = field_type_to_model.get(field_type)
205
+ if not model_class:
206
+ raise ValueError(f"No model class found for field type: {field_type}")
207
+
208
+ return model_class
209
+
210
+
211
+ class ManualTaskTextField(ManualTaskFieldBase):
212
+ """Schema for text field definition."""
213
+
214
+ field_type: Annotated[
215
+ Literal[ManualTaskFieldType.text], Field(description="Type of the field")
216
+ ]
217
+ field_metadata: Annotated[
218
+ ManualTaskTextFieldMetadata,
219
+ Field(description="Field metadata and configuration"),
220
+ ]
221
+
222
+
223
+ class ManualTaskCheckboxField(ManualTaskFieldBase):
224
+ """Schema for checkbox field definition."""
225
+
226
+ field_type: Annotated[
227
+ Literal[ManualTaskFieldType.checkbox], Field(description="Type of the field")
228
+ ]
229
+ field_metadata: Annotated[
230
+ ManualTaskCheckboxFieldMetadata,
231
+ Field(description="Field metadata and configuration"),
232
+ ]
233
+
234
+
235
+ class ManualTaskAttachmentField(ManualTaskFieldBase):
236
+ """Schema for attachment field definition."""
237
+
238
+ field_type: Annotated[
239
+ Literal[ManualTaskFieldType.attachment], Field(description="Type of the field")
240
+ ]
241
+ field_metadata: Annotated[
242
+ ManualTaskAttachmentFieldMetadata,
243
+ Field(description="Field metadata and configuration"),
244
+ ]
245
+
246
+
247
+ # Type alias for all field types
248
+ ManualTaskField = ManualTaskFieldBase
249
+
250
+
251
+ class ManualTaskConfigCreate(FidesSchema):
252
+ """Schema for creating a manual task configuration."""
253
+
254
+ model_config = ConfigDict(extra="forbid")
255
+
256
+ task_id: Annotated[
257
+ str, Field(description="ID of the task this configuration belongs to")
258
+ ]
259
+ config_type: Annotated[
260
+ ManualTaskConfigurationType, Field(description="Type of configuration")
261
+ ]
262
+ fields: Annotated[
263
+ list[ManualTaskFieldBase], Field(description="List of field definitions")
264
+ ]
265
+
266
+
267
+ class ManualTaskConfigResponse(FidesSchema):
268
+ """Schema for manual task configuration response."""
269
+
270
+ model_config = ConfigDict(extra="forbid")
271
+
272
+ id: Annotated[str, Field(description="Configuration ID")]
273
+ task_id: Annotated[str, Field(description="Task ID")]
274
+ config_type: Annotated[
275
+ ManualTaskConfigurationType, Field(description="Type of configuration")
276
+ ]
277
+ version: Annotated[int, Field(description="Version of the configuration")]
278
+ is_current: Annotated[
279
+ bool, Field(description="Whether this is the current version")
280
+ ]
281
+ fields: Annotated[
282
+ list[ManualTaskFieldBase], Field(description="List of field definitions")
283
+ ]
284
+ created_at: Annotated[datetime, Field(description="Creation timestamp")]
285
+ updated_at: Annotated[datetime, Field(description="Last update timestamp")]
286
+
287
+
288
+ class ManualTaskConfigUpdate(FidesSchema):
289
+ """Schema for updating a manual task configuration."""
290
+
291
+ model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True)
292
+
293
+ task_id: Annotated[str, Field(description="ID of the task")]
294
+ config_type: Annotated[
295
+ ManualTaskConfigurationType, Field(description="Type of configuration")
296
+ ]
297
+ fields: Annotated[
298
+ list[ManualTaskFieldBase], Field(description="List of field definitions")
299
+ ]
300
+
301
+
302
+ class ManualTaskConfigFieldResponse(FidesSchema):
303
+ """Schema for manual task configuration field response."""
304
+
305
+ model_config = ConfigDict(extra="forbid")
306
+
307
+ field_key: Annotated[str, Field(description="Unique key for the field")]
308
+ field_type: Annotated[ManualTaskFieldType, Field(description="Type of the field")]
309
+ field_metadata: Annotated[
310
+ ManualTaskFieldMetadata, Field(description="Field metadata and configuration")
311
+ ]
@@ -38,7 +38,7 @@ class ManualTaskLogStatus(str, Enum):
38
38
 
39
39
  created = "created"
40
40
  updated = "updated"
41
- in_processing = "in_processing"
41
+ in_progress = "in_progress"
42
42
  complete = "complete"
43
43
  error = "error"
44
44
  retrying = "retrying"
@@ -32,7 +32,7 @@ class StatusType(str, EnumType):
32
32
  list[StatusType]: List of valid transitions
33
33
  """
34
34
  if current_status == cls.pending:
35
- return [cls.in_progress, cls.failed]
35
+ return [cls.in_progress, cls.failed, cls.completed]
36
36
  if current_status == cls.in_progress:
37
37
  return [cls.completed, cls.failed]
38
38
  if current_status == cls.completed:
@@ -77,6 +77,7 @@ class PrivacyRequestSource(str, EnumType):
77
77
  - Consent Webhook: Request created as a side-effect of a consent webhook request (bidirectional consent)
78
78
  - Fides.js: Request created as a side-effect of a privacy preference update from Fides.js
79
79
  - Dataset Test: Standalone dataset test
80
+ - Janus SDK: Request created from the Mobile SDK
80
81
  """
81
82
 
82
83
  privacy_center = "Privacy Center"
@@ -84,6 +85,7 @@ class PrivacyRequestSource(str, EnumType):
84
85
  consent_webhook = "Consent Webhook"
85
86
  fides_js = "Fides.js"
86
87
  dataset_test = "Dataset Test"
88
+ janus_sdk = "Janus SDK"
87
89
 
88
90
 
89
91
  class PrivacyRequestCreate(FidesSchema):
fides/api/util/cache.py CHANGED
@@ -174,6 +174,7 @@ def _determine_redis_db_index(
174
174
  - If *not* running under xdist, always use DB 1.
175
175
 
176
176
  2. Non-test mode: return the value already present in `CONFIG.redis.db_index`
177
+ (or CONFIG.redis.read_only_db_index` if read_only is True)
177
178
  """
178
179
 
179
180
  # 1. Test mode logic
@@ -261,18 +262,20 @@ def get_read_only_cache() -> FidesopsRedis:
261
262
  ssl_ca_certs=CONFIG.redis.read_only_ssl_ca_certs,
262
263
  ssl_cert_reqs=CONFIG.redis.read_only_ssl_cert_reqs,
263
264
  )
264
- logger.debug("New read-only Redis connection created.")
265
265
 
266
266
  try:
267
+ # Test the connection by attempting to ping the Redis server
267
268
  connected = _read_only_connection.ping()
268
- logger.debug("Read-only Redis connection succeeded.")
269
- except ConnectionErrorFromRedis:
269
+ logger.debug("Read-only Redis connection established successfully.")
270
+ except Exception as e:
271
+ logger.error(f"Failed to connect to read-only Redis: {e}")
270
272
  connected = False
271
273
 
272
274
  if not connected:
273
275
  logger.error(
274
276
  "Unable to establish read-only Redis connection. Returning writeable cache connection instead."
275
277
  )
278
+ # If we can't connect to the read-only cache, fall back to the regular cache
276
279
  return get_cache()
277
280
 
278
281
  return _read_only_connection
@@ -77,35 +77,99 @@ class RedisSettings(FidesSettings):
77
77
  default="",
78
78
  description="The network address for the read-only Redis cache.",
79
79
  )
80
- read_only_port: int = Field(
81
- default=6379,
82
- description="The port at which the read-only Redis cache will be accessible.",
80
+ # Read-only Redis settings with automatic fallback behavior
81
+ # Field validators will populate these fields with the corresponding writer settings if not provided
82
+ # The order here is important, these must be defined after the writer settings
83
+ read_only_port: int = Field( # type: ignore[assignment]
84
+ default=None,
85
+ description="The port at which the read-only Redis cache will be accessible. If not provided, the `port` setting will be used.",
83
86
  )
84
- read_only_user: str = Field(
85
- default="",
86
- description="The user with which to login to the read-only Redis cache.",
87
+ read_only_user: str = Field( # type: ignore[assignment]
88
+ default=None,
89
+ description="The user with which to login to the read-only Redis cache. If not provided, the `user` setting will be used.",
87
90
  )
88
- read_only_password: str = Field(
89
- default="",
90
- description="The password with which to login to the read-only Redis cache.",
91
+ read_only_password: str = Field( # type: ignore[assignment]
92
+ default=None,
93
+ description="The password with which to login to the read-only Redis cache. If not provided, the `password` setting will be used.",
91
94
  )
92
- read_only_db_index: int = Field(
93
- default=0,
94
- description="The application will use this index in the read-only Redis cache to cache data.",
95
+ read_only_db_index: int = Field( # type: ignore[assignment]
96
+ default=None,
97
+ description="The application will use this index in the read-only Redis cache to cache data. If not provided, the `db_index` setting will be used.",
95
98
  )
96
- read_only_ssl: bool = Field(
97
- default=False,
98
- description="Whether the application's connections to the read-only cache should be encrypted using TLS.",
99
+ read_only_ssl: bool = Field( # type: ignore[assignment]
100
+ default=None,
101
+ description="Whether the application's connections to the read-only cache should be encrypted using TLS. If not provided, the `ssl` setting will be used.",
99
102
  )
100
103
  read_only_ssl_cert_reqs: Optional[str] = Field(
101
- default="required",
102
- description="If using TLS encryption, set this to 'required' if you wish to enforce the read-only Redis cache to provide a certificate. Note that not all cache providers support this without setting ssl_ca_certs (e.g. AWS Elasticache).",
104
+ default=None,
105
+ description="If using TLS encryption, set this to 'required' if you wish to enforce the read-only Redis cache to provide a certificate. Note that not all cache providers support this without setting ssl_ca_certs (e.g. AWS Elasticache). If not provided, the `ssl_cert_reqs` setting will be used.",
103
106
  )
104
- read_only_ssl_ca_certs: str = Field(
105
- default="",
106
- description="If using TLS encryption rooted with a custom Certificate Authority, set this to the path of the CA certificate.",
107
+ read_only_ssl_ca_certs: str = Field( # type: ignore[assignment]
108
+ default=None,
109
+ description="If using TLS encryption rooted with a custom Certificate Authority, set this to the path of the CA certificate. If not provided, the `ssl_ca_certs` setting will be used.",
107
110
  )
108
111
 
112
+ # Field validators for automatic fallback behavior
113
+ @field_validator("read_only_port", mode="before")
114
+ @classmethod
115
+ def resolve_read_only_port(cls, v: Optional[int], info: ValidationInfo) -> int:
116
+ """Resolves the read-only port setting by falling back to the `port` value if no `read_only_port` is specified."""
117
+ if v is None:
118
+ return info.data["port"]
119
+ return v
120
+
121
+ @field_validator("read_only_user", mode="before")
122
+ @classmethod
123
+ def resolve_read_only_user(cls, v: Optional[str], info: ValidationInfo) -> str:
124
+ """Resolves the read-only user setting by falling back to the `user` value if no `read_only_user` is specified."""
125
+ if v is None:
126
+ return info.data["user"]
127
+ return v
128
+
129
+ @field_validator("read_only_password", mode="before")
130
+ @classmethod
131
+ def resolve_read_only_password(cls, v: Optional[str], info: ValidationInfo) -> str:
132
+ """Resolves the read-only password setting by falling back to the `password` value if no `read_only_password` is specified."""
133
+ if v is None:
134
+ return info.data["password"]
135
+ return v
136
+
137
+ @field_validator("read_only_db_index", mode="before")
138
+ @classmethod
139
+ def resolve_read_only_db_index(cls, v: Optional[int], info: ValidationInfo) -> int:
140
+ """Resolves the read-only db_index setting by falling back to the `db_index` value if no `read_only_db_index` is specified."""
141
+ if v is None:
142
+ return info.data["db_index"]
143
+ return v
144
+
145
+ @field_validator("read_only_ssl", mode="before")
146
+ @classmethod
147
+ def resolve_read_only_ssl(cls, v: Optional[bool], info: ValidationInfo) -> bool:
148
+ """Resolves the read-only ssl setting by falling back to the `ssl` value if no `read_only_ssl` is specified."""
149
+ if v is None:
150
+ return info.data["ssl"]
151
+ return v
152
+
153
+ @field_validator("read_only_ssl_cert_reqs", mode="before")
154
+ @classmethod
155
+ def resolve_read_only_ssl_cert_reqs(
156
+ cls, v: Optional[str], info: ValidationInfo
157
+ ) -> Optional[str]:
158
+ """Resolves the read-only ssl_cert_reqs setting by falling back to the `ssl_cert_reqs` value if no `read_only_ssl_cert_reqs` is specified."""
159
+ if v is None:
160
+ return info.data["ssl_cert_reqs"]
161
+ return v
162
+
163
+ @field_validator("read_only_ssl_ca_certs", mode="before")
164
+ @classmethod
165
+ def resolve_read_only_ssl_ca_certs(
166
+ cls, v: Optional[str], info: ValidationInfo
167
+ ) -> str:
168
+ """Resolves the read-only ssl_ca_certs setting by falling back to the `ssl_ca_certs` value if no `read_only_ssl_ca_certs` is specified."""
169
+ if v is None:
170
+ return info.data["ssl_ca_certs"]
171
+ return v
172
+
109
173
  # This relies on other values to get built so must be last
110
174
  connection_url: Optional[str] = Field(
111
175
  default=None,
@@ -130,49 +194,48 @@ class RedisSettings(FidesSettings):
130
194
  # If the whole URL is provided via the config, preference that
131
195
  return v
132
196
 
197
+ # Determine which set of settings to use based on field name
133
198
  is_read_only = info.field_name == "read_only_connection_url"
134
199
 
135
- connection_protocol = "redis"
136
- params_str = ""
137
- use_tls = (
138
- info.data.get("read_only_ssl")
139
- if is_read_only
140
- else info.data.get("ssl", False)
141
- )
142
-
143
- # These vars are intentionally fetched with `or ""` as the default to account
144
- # for the edge case where `None` is explicitly set in `values` by Pydantic because
145
- # it is not overridden by the config file or an env var
200
+ # Extract settings - fallbacks already resolved by field validators for read-only fields
146
201
  user = (
147
- info.data.get("read_only_user", "")
148
- if is_read_only
149
- else info.data.get("user", "")
202
+ info.data["read_only_user"] if is_read_only else info.data.get("user", "")
150
203
  )
151
204
  password = (
152
- info.data.get("read_only_password", "")
205
+ info.data["read_only_password"]
153
206
  if is_read_only
154
207
  else info.data.get("password", "")
155
208
  )
209
+
156
210
  db_index = (
157
- info.data.get("read_only_db_index", "")
211
+ info.data["read_only_db_index"]
158
212
  if is_read_only
159
213
  else info.data.get("db_index", "")
160
214
  )
215
+ use_tls = (
216
+ info.data["read_only_ssl"] if is_read_only else info.data.get("ssl", False)
217
+ )
218
+
219
+ connection_protocol = "redis"
220
+ params_str = ""
221
+
161
222
  if use_tls:
162
223
  # If using TLS update the connection URL format
163
224
  connection_protocol = "rediss"
164
- cert_reqs = (
225
+
226
+ ssl_cert_reqs = (
165
227
  info.data.get("read_only_ssl_cert_reqs", "none")
166
228
  if is_read_only
167
229
  else info.data.get("ssl_cert_reqs", "none")
168
230
  )
169
- params = {"ssl_cert_reqs": quote_plus(cert_reqs)}
170
-
171
231
  ssl_ca_certs = (
172
- info.data.get("read_only_ssl_ca_certs", "")
232
+ info.data["read_only_ssl_ca_certs"]
173
233
  if is_read_only
174
234
  else info.data.get("ssl_ca_certs", "")
175
235
  )
236
+
237
+ # Build SSL parameters
238
+ params = {"ssl_cert_reqs": quote_plus(ssl_cert_reqs or "none")}
176
239
  if ssl_ca_certs:
177
240
  params["ssl_ca_certs"] = quote(ssl_ca_certs, safe="/")
178
241
  params_str = "?" + urlencode(params, quote_via=quote, safe="/")
@@ -183,17 +246,15 @@ class RedisSettings(FidesSettings):
183
246
  if password or user:
184
247
  auth_prefix = f"{quote_plus(user)}:{quote_plus(password)}@"
185
248
 
249
+ # For host, we don't have a fallback - read replica should be a different host
186
250
  host = (
187
251
  info.data.get("read_only_host", "")
188
252
  if is_read_only
189
253
  else info.data.get("host", "")
190
254
  )
191
255
  port = (
192
- info.data.get("read_only_port", "")
193
- if is_read_only
194
- else info.data.get("port", "")
256
+ info.data["read_only_port"] if is_read_only else info.data.get("port", "")
195
257
  )
196
-
197
258
  # Only include database index in URL if it's not the default (0)
198
259
  db_path = f"{db_index}" if db_index != 0 else ""
199
260