ethyca-fides 2.69.1rc0__py2.py3-none-any.whl → 2.76.0rc2__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.
- {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/METADATA +9 -6
- {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/RECORD +488 -361
- fides/_version.py +3 -3
- fides/api/alembic/alembic.ini +5 -1
- fides/api/alembic/migrations/env.py +7 -1
- fides/api/alembic/migrations/versions/0eef0016cf06_adding_oauth2_config_for_.py +69 -0
- fides/api/alembic/migrations/versions/303287c70600_migrate_resource_type_from_enum_to_.py +99 -0
- fides/api/alembic/migrations/versions/30369bb8ae01_add_webmonitorgroupjob_model.py +67 -0
- fides/api/alembic/migrations/versions/3efe14d4469a_adds_new_experience_configs_for_vendor_.py +79 -0
- fides/api/alembic/migrations/versions/4bfbeff34611_add_polling_status.py +68 -0
- fides/api/alembic/migrations/versions/4d8c0fcc5771_adding_default_system_groups.py +78 -0
- fides/api/alembic/migrations/versions/5fa78b1f324d_add_event_audit_table.py +82 -0
- fides/api/alembic/migrations/versions/65a1bc82ae09_adds_experience_config_for_delete_.py +53 -0
- fides/api/alembic/migrations/versions/67d0e389b003_update_consentstatus_enum.py +47 -0
- fides/api/alembic/migrations/versions/795f46f656c0_migrate_field_type_from_enum_to_string.py +61 -0
- fides/api/alembic/migrations/versions/7db29f9cd77b_create_new_sub_request_table.py +95 -0
- fides/api/alembic/migrations/versions/918aefc950c9_create_digest_conditional_dependencies.py +125 -0
- fides/api/alembic/migrations/versions/9caf76161e55_make_user_assigned_data_uses_nullable_.py +64 -0
- fides/api/alembic/migrations/versions/9e0dcbf67b9f_add_digest_config.py +84 -0
- fides/api/alembic/migrations/versions/a55e12c2c2df_add_tagging_instructions_to_data_.py +29 -0
- fides/api/alembic/migrations/versions/a8e0c016afd_add_classification_benchmark_table.py +126 -0
- fides/api/alembic/migrations/versions/b97e92b038d2_add_digest_execution_model.py +117 -0
- fides/api/alembic/migrations/versions/b9bfa12c167b_add_not_applicable_to_asset_consentstatus.py +46 -0
- fides/api/alembic/migrations/versions/c09e76282dd1_add_privacy_request_duplication_cols.py +64 -0
- fides/api/alembic/migrations/versions/cd8649be3a2b_add_classifications_and_user_assigned_.py +74 -0
- fides/api/alembic/migrations/versions/e2cda8d6abc3_add_dismissed_in_activity_view_to_.py +29 -0
- fides/api/alembic/migrations/versions/f108fa05c579_adds_optional_duration_field_to_assets.py +28 -0
- fides/api/alembic/migrations/versions/f36ce1bde293_add_system_groups.py +132 -0
- fides/api/alembic/migrations/versions/fd7571bef683_adds_new_fields_to_messagingconfig_for_.py +31 -0
- fides/api/alembic/migrations/versions/xx_2025_10_17_1603_5093e92e2a5a_add_consent_data_v3_to_the_database.py +72 -0
- fides/api/alembic/migrations/versions/xx_2025_10_27_1834_67f0f2f4748e_adding_identity_definition_model.py +45 -0
- fides/api/alembic/migrations/versions/xx_2025_10_29_1659_80d28dea3b6b_added_duplicate_group_table.py +79 -0
- fides/api/alembic/migrations/versions/xx_2025_11_05_0200_f1a2b3c4d5e6_create_staged_resource_error_table.py +82 -0
- fides/api/alembic/migrations/versions/xx_2025_11_07_1709_56fe6fad2d89_add_notice_display_order.py +47 -0
- fides/api/alembic/migrations/versions/xx_2025_11_10_1200_a1b2c3d4e5f6_add_test_datastore_to_connectiontype.py +53 -0
- fides/api/alembic/migrations/versions/xx_2025_11_11_1317_7d82c8fc4c34_store_saas_template_datasets.py +68 -0
- fides/api/alembic/migrations/versions/xx_2025_11_12_1430_b2c3d4e5f6a7_add_default_identity_definitions.py +81 -0
- fides/api/alembic/migrations/versions/xx_2025_11_25_1854_3ff6449c099e_add_index_on_providedidentity_privacy_.py +50 -0
- fides/api/api/v1/api.py +2 -0
- fides/api/api/v1/endpoints/admin.py +39 -0
- fides/api/api/v1/endpoints/connection_endpoints.py +191 -47
- fides/api/api/v1/endpoints/connector_template_endpoints.py +167 -0
- fides/api/api/v1/endpoints/generic_overrides.py +90 -15
- fides/api/api/v1/endpoints/messaging_endpoints.py +164 -34
- fides/api/api/v1/endpoints/pre_approval_webhook_endpoints.py +5 -5
- fides/api/api/v1/endpoints/privacy_request_endpoints.py +231 -46
- fides/api/api/v1/endpoints/saas_config_endpoints.py +63 -92
- fides/api/api/v1/endpoints/storage_endpoints.py +5 -1
- fides/api/api/v1/endpoints/system.py +157 -100
- fides/api/api/v1/endpoints/user_endpoints.py +17 -4
- fides/api/app_setup.py +1 -3
- fides/api/common_exceptions.py +8 -0
- fides/api/db/base.py +8 -0
- fides/api/db/crud.py +30 -2
- fides/api/db/database.py +261 -4
- fides/api/db/safe_crud.py +377 -0
- fides/api/db/seed.py +35 -1
- fides/api/email_templates/get_email_template.py +3 -0
- fides/api/email_templates/template_names.py +1 -0
- fides/api/email_templates/templates/external_user_welcome.html +9 -5
- fides/api/email_templates/templates/manual_task_digest.html +316 -0
- fides/api/main.py +2 -0
- fides/api/migrations/post_upgrade_index_creation.py +20 -0
- fides/api/models/asset.py +17 -1
- fides/api/models/attachment.py +1 -0
- fides/api/models/conditional_dependency/__init__.py +0 -0
- fides/api/models/conditional_dependency/conditional_dependency_base.py +311 -0
- fides/api/models/connection_oauth_credentials.py +57 -0
- fides/api/models/connectionconfig.py +11 -1
- fides/api/models/detection_discovery/__init__.py +4 -0
- fides/api/models/detection_discovery/classification_benchmark.py +140 -0
- fides/api/models/detection_discovery/core.py +78 -3
- fides/api/models/detection_discovery/monitor_task.py +3 -1
- fides/api/models/detection_discovery/staged_resource_error.py +25 -0
- fides/api/models/detection_discovery/web_monitor.py +61 -0
- fides/api/models/digest/__init__.py +16 -0
- fides/api/models/digest/conditional_dependencies.py +275 -0
- fides/api/models/digest/digest_config.py +110 -0
- fides/api/models/digest/digest_execution.py +142 -0
- fides/api/models/event_audit.py +85 -0
- fides/api/models/experience_notices.py +6 -1
- fides/api/models/fides_user.py +9 -0
- fides/api/models/identity_definition.py +66 -0
- fides/api/models/location_regulation_selections.py +22 -0
- fides/api/models/manual_task/conditional_dependency.py +29 -87
- fides/api/models/manual_webhook.py +17 -6
- fides/api/models/messaging.py +30 -10
- fides/api/models/messaging_template.py +14 -0
- fides/api/models/policy.py +27 -0
- fides/api/models/privacy_experience.py +41 -0
- fides/api/models/privacy_notice.py +196 -13
- fides/api/models/privacy_preference.py +2 -0
- fides/api/models/privacy_request/duplicate_group.py +84 -0
- fides/api/models/privacy_request/privacy_request.py +154 -8
- fides/api/models/privacy_request/provided_identity.py +22 -1
- fides/api/models/privacy_request/request_task.py +98 -1
- fides/api/models/privacy_request/webhook.py +3 -1
- fides/api/models/saas_template_dataset.py +63 -0
- fides/api/models/sql_models.py +161 -7
- fides/api/models/system_group.py +85 -0
- fides/api/models/taxonomy.py +91 -9
- fides/api/models/v3/__init__.py +0 -0
- fides/api/models/v3/privacy_preferences.py +85 -0
- fides/api/models/worker_task.py +8 -0
- fides/api/oauth/roles.py +4 -0
- fides/api/schemas/application_config.py +32 -1
- fides/api/schemas/connection_configuration/connection_config.py +1 -30
- fides/api/schemas/connection_configuration/connection_oauth_config.py +42 -0
- fides/api/schemas/connection_configuration/connection_secrets_mongodb.py +15 -3
- fides/api/schemas/connection_configuration/connection_secrets_mssql.py +5 -0
- fides/api/schemas/messaging/messaging.py +49 -66
- fides/api/schemas/messaging/messaging_secrets_docs_only.py +1 -1
- fides/api/schemas/messaging/shared_schemas.py +102 -0
- fides/api/schemas/oauth.py +2 -1
- fides/api/schemas/privacy_center_config.py +29 -5
- fides/api/schemas/privacy_request.py +44 -7
- fides/api/schemas/saas/async_polling_configuration.py +81 -0
- fides/api/schemas/saas/connector_template.py +14 -0
- fides/api/schemas/saas/saas_config.py +12 -20
- fides/api/schemas/system.py +8 -0
- fides/api/schemas/taxonomy_extensions.py +8 -0
- fides/api/schemas/user.py +2 -2
- fides/api/service/async_dsr/handlers/__init__.py +0 -0
- fides/api/service/async_dsr/handlers/polling_attachment_handler.py +155 -0
- fides/api/service/async_dsr/handlers/polling_request_handler.py +88 -0
- fides/api/service/async_dsr/handlers/polling_response_handler.py +261 -0
- fides/api/service/async_dsr/handlers/polling_sub_request_handler.py +123 -0
- fides/api/service/async_dsr/strategies/__init__.py +0 -0
- fides/api/service/async_dsr/strategies/async_dsr_strategy.py +52 -0
- fides/api/service/async_dsr/strategies/async_dsr_strategy_callback.py +199 -0
- fides/api/service/async_dsr/strategies/async_dsr_strategy_factory.py +72 -0
- fides/api/service/async_dsr/strategies/async_dsr_strategy_polling.py +691 -0
- fides/api/service/async_dsr/utils.py +130 -0
- fides/api/service/connectors/base_erasure_email_connector.py +7 -0
- fides/api/service/connectors/bigquery_connector.py +34 -16
- fides/api/service/connectors/fides/fides_client.py +63 -1
- fides/api/service/connectors/http_connector.py +48 -12
- fides/api/service/connectors/microsoft_sql_server_connector.py +6 -1
- fides/api/service/connectors/mongodb_connector.py +74 -9
- fides/api/service/connectors/query_configs/saas_query_config.py +160 -79
- fides/api/service/connectors/saas/connector_registry_service.py +42 -135
- fides/api/service/connectors/saas_connector.py +116 -76
- fides/api/service/connectors/sql_connector.py +14 -4
- fides/api/service/deps.py +25 -2
- fides/api/service/messaging/message_dispatch_service.py +98 -20
- fides/api/service/messaging/messaging_crud_service.py +5 -9
- fides/api/service/privacy_request/attachment_handling.py +9 -2
- fides/api/service/privacy_request/dsr_package/dsr_report_builder.py +17 -9
- fides/api/service/privacy_request/dsr_package/templates/attachments_index.html +41 -30
- fides/api/service/privacy_request/dsr_package/templates/clickme.html +68 -0
- fides/api/service/privacy_request/dsr_package/templates/dataset_index.html +30 -27
- fides/api/service/privacy_request/duplication_detection.py +439 -0
- fides/api/service/privacy_request/email_batch_service.py +2 -1
- fides/api/service/privacy_request/request_runner_service.py +92 -91
- fides/api/service/privacy_request/request_service.py +74 -90
- fides/api/service/saas_request/saas_request_override_factory.py +71 -1
- fides/api/service/storage/streaming/schemas.py +27 -19
- fides/api/service/storage/streaming/smart_open_client.py +2 -2
- fides/api/service/storage/streaming/smart_open_streaming_storage.py +238 -147
- fides/api/service/storage/util.py +20 -106
- fides/api/service/strategy.py +6 -3
- fides/api/task/conditional_dependencies/privacy_request/__init__.py +0 -0
- fides/api/task/conditional_dependencies/privacy_request/convenience_fields.py +155 -0
- fides/api/task/conditional_dependencies/privacy_request/privacy_request_data.py +140 -0
- fides/api/task/conditional_dependencies/privacy_request/schemas.py +212 -0
- fides/api/task/conditional_dependencies/sql_schemas.py +301 -0
- fides/api/task/conditional_dependencies/sql_translator.py +757 -0
- fides/api/task/conditional_dependencies/util.py +111 -0
- fides/api/task/execute_request_tasks.py +34 -13
- fides/api/task/filter_results.py +35 -2
- fides/api/task/graph_runners.py +2 -32
- fides/api/task/graph_task.py +42 -12
- fides/api/task/manual/manual_task_conditional_evaluation.py +33 -28
- fides/api/task/manual/manual_task_graph_task.py +4 -1
- fides/api/task/manual/manual_task_utils.py +68 -26
- fides/api/task/scheduler_utils.py +39 -0
- fides/api/tasks/__init__.py +15 -1
- fides/api/util/cache.py +5 -1
- fides/api/util/connection_util.py +101 -218
- fides/api/util/event_audit_util.py +230 -0
- fides/api/util/filter_utils.py +0 -3
- fides/api/util/fuzzy_search_utils.py +7 -1
- fides/api/util/lock.py +13 -3
- fides/api/util/logger.py +58 -4
- fides/api/util/logger_context_utils.py +3 -1
- fides/api/util/masking_util.py +31 -0
- fides/api/util/memory_watchdog.py +118 -0
- fides/api/util/rate_limit.py +25 -7
- fides/api/util/saas_config_updater.py +76 -0
- fides/api/util/saas_util.py +28 -1
- fides/api/worker/__init__.py +6 -0
- fides/common/api/scope_registry.py +6 -7
- fides/common/api/v1/urn_registry.py +15 -3
- fides/config/__init__.py +11 -2
- fides/config/celery_settings.py +42 -0
- fides/config/config_proxy.py +10 -0
- fides/config/duplicate_detection_settings.py +31 -0
- fides/config/execution_settings.py +6 -6
- fides/config/security_settings.py +4 -1
- fides/config/utils.py +5 -0
- fides/data/language/languages.yml +2 -0
- fides/service/connection/__init__.py +0 -0
- fides/service/connection/connection_service.py +651 -0
- fides/service/dataset/dataset_service.py +39 -0
- fides/service/event_audit_service.py +109 -0
- fides/service/messaging/aws_ses_service.py +2 -4
- fides/service/messaging/messaging_service.py +75 -74
- fides/service/privacy_request/privacy_request_service.py +345 -100
- fides/service/system/__init__.py +0 -0
- fides/service/system/system_service.py +153 -0
- fides/service/taxonomy/handlers/legacy_handler.py +3 -3
- fides/service/taxonomy/taxonomy_service.py +64 -18
- fides/ui-build/static/admin/404.html +1 -1
- fides/ui-build/static/admin/_next/static/chunks/1099-688fa865621531cc.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1115-7fd171dac1eb0e51.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1276.deb10ae2643f8463.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1438-8a33b3834d6e43f3.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{6148-59a59d5c5925344f.js → 1533-84e250d1f26e6d7d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/1821-c1daa160f492aacf.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1840-359ee056e4cf6629.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{1975.78e719130cfe3fd6.js → 1975.bef017bc80e2012c.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/2040-70972e15960d9afe.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/2121.321b0fd3932164d4.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/2397-3434603a97f3f5d6.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/2921-49ed0ed897832958.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3150-da5406b80d25fe6d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3214-90ce0a366b0f461a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3377-02bf9780fd383d94.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3615-5e2d062d684b8fa1.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3655-5e1ba5dd68b5ec48.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3729-31ff8ba51491bf21.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3872-cff30ca0844fe2b1.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3931-8bedde156fe83564.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/401-582d9970d89deefe.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4093-7e47408c28de5375.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{4259.d1507e0db19cbed7.js → 4259.05038c9b78467244.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/431-e01ee730c8ad9ece.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4322-f6aeff6880726c83.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4339-04a715ab07122744.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4496-ccbce2459174e0d6.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/454-d5c2c84f1a14e4f1.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4589-c1d83c6a8dab4d30.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4809-a8f4a108a42f53ed.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4903-19c0bc07a956dfa8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4910-d990773601f794c1.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5185-96423702fba70ced.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5258-4e308cca01d59367.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5487-5c3501754bf027ba.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/549-1bdc3e6f3264c020.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5505-43b9c39491b88e08.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5698.2135391a128cc373.js +164 -0
- fides/ui-build/static/admin/_next/static/chunks/5783-016dfcee8e49bf61.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5826-4db99ea4e5077911.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/590-be447cacf12419dd.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6084-91badbc6569a0efb.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6344-026cb323c1d49926.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6362-ba0e12f2fc4cad94.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6853-882889659769d7b4.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6882-bb1b469d7d7f5335.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6954-0dcf22a9aabe39c5.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7170-46db82bb5b55e856.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7218-2ace8c82e3e7eb74.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7245-1cdafb35f289861b.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7630-7f75ab7b8df42eb3.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7654-2e9a8be02e41769a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/8212-348ddd2b6933db70.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/9014-eeae6f581158e645.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{5596-bb601cbf40e47a0f.js → 9195-da717d324917b049.js} +3 -3
- fides/ui-build/static/admin/_next/static/chunks/9450-b7b7bb1d755ecf57.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{9676.9fd9552ef744c717.js → 9676.1f395eeb9cc34968.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/9826-1078e46f3ac0b688.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/9911-ece086f2230e34f0.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{404-471a6b18e712f050.js → 404-800be6996aaa999c.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{_app-fcdad91f6f66292b.js → _app-de4b578c904df772.js} +57 -220
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/manual-f12020b82dd4bd1a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/multiple-a911b7990371704d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-ad585b79953c2753.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-406170eaae4329c6.js → add-vendors-bb263d394ca1c8fa.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-6907c368d8611c44.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-f80cf2d3966816fd.js → [id]-c32f381af358149b.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{new-e74cb5ea87f15b40.js → new-6efb3c069d8b47dd.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience-1975c529905eea9b.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-b378576cba255609.js → [id]-b05331178928ab52.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-2ca1de7b88094ab0.js → new-516834e930bb0d0d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-985717f2565f9d9d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/{properties-226efa1dcd41437f.js → properties-2be773e08498e40c.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-850afb74f4192e87.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent-b63d1e395d879b86.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn]-5b28f0f674ea87bd.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/{[projectUrn]-04cfe2cfba7b7cd8.js → [projectUrn]-676177e2f3c9c2a2.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-794906929efb8e1d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/[resourceUrn]-3ccbf7c0d06507b9.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-1ea0b24d306b1e67.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/datastore/[monitorId]-d4861a4a218bb65a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/datastore-4498881c26f1458d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/infrastructure/[monitorId]-66bd265044daf97d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/infrastructure-c9c79fa8576a4f77.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website/[monitorId]/[systemId]-60cacc3232c2eead.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website/[monitorId]-437bd64a3016de36.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website-5b3e0009d442bc3f.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-8349248c2da970a6.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-6919a1d6cadaa46b.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-8f736b078e9842da.js → [resourceUrn]-1a50d421897d3da1.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-eb814e3c22807871.js → detection-49509414a15e8393.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-6875b7783fcfda2f.js → [resourceUrn]-1a1bb80b586d0c0f.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-172dbd7740e212ca.js → discovery-49de61df1e8e7fba.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datamap-c2719f5cff20c0f8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/{[...subfieldNames]-dfd71c1e9c458b89.js → [...subfieldNames]-415015aebab60436.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/{[collectionName]-7cdc42ec5493b83d.js → [collectionName]-5accb09715b5122d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-aebecca1d8ec5f98.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-9551a82ddec9f909.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset-72f8fe47beef0f09.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/[id]-3a8aa3f633528e88.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-87512616f35ec6da.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-2f1bf4eac7aa55fd.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{fides-js-docs-1f4335dca5c09860.js → fides-js-docs-5235760b3e508d7d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/index-8d67cd2872cb682a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-7a631df29cd0e31a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations-ea3bc43cdaf273de.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/new-privacy-requests-5d8632bba1b81cd4.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests/[id]-92e01822ecde8fb8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests/new-1256cf6d3f6794e0.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests-0daac00911d27617.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers/[key]-2d976fe5e8ba0a3a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers/new-7766ba497b863740.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers-f2880d2ed4734270.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates/[id]-669f585c3458faff.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates/add-template-c79e7724e4bc3899.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates-891654e8dc13965c.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications-40c8148244c5d347.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-1e86f3e28bd23ed6.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/AntForm-9b7bd8c38f02c091.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikAntFormItem-b18a53a940cf9e19.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikControlled-6d028d7450e77578.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikField-8399083ee2cd8cc2.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/forms-0a910125cdb2b3b8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-acc90b6f7fe915cb.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-bbc42026f2685438.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure-c08ca6ad21c99799.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-77c2db582f8823bc.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-e784c05d056b2371.js → [id]-74ccea4868408e3d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-0a7a2db148a7561a.js → add-property-7d9f09bfe9d44dfc.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{properties-da734840e4f9d04b.js → properties-cd77bc30672bb1fa.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-cc3bd9540132d5ed.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/sandbox/privacy-notices-7ce7d720107ab4b5.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/alpha-68eaac2d79133679.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/about-6c4904c157477285.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-ae789892343c24f5.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-13ee1b331ced0846.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields/[id]-ee4e43692336a330.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields/new-ca51d794abfcbf25.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-ecd1dc5db8e81409.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/domain-records-df06f7e2f668c540.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-da0c77bd510c6c51.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/email-templates-950b0c115bf673d8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-2e635dcd11b78224.js → locations-7e36cb4756973a9d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-a0e5ed486d24ccf3.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/privacy-requests-3cdebafb6870d3ad.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-7c02e469d8c5bd74.js → regulations-159aad34f1021320.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-dbd1a64090ad0946.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]-7d042497a57a3788.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/systems-21f1172e73dfc9f0.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-e553161e6338ee48.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management/{new-92f52c43f522a350.js → new-efc4af017723e57a.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/{[id]-64452dfae2c5e614.js → [id]-b152319d67372ee4.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management-dba8692491f7935e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/webpack-09ca52bc7beb0b43.js +1 -0
- fides/ui-build/static/admin/_next/static/css/012b10627a654d5c.css +1 -0
- fides/ui-build/static/admin/_next/static/css/05d05fc31d09638b.css +1 -0
- fides/ui-build/static/admin/_next/static/css/0fd6e0884cfcc5f3.css +1 -0
- fides/ui-build/static/admin/_next/static/css/14ba79c49597d37a.css +1 -0
- fides/ui-build/static/admin/_next/static/css/{34a7eb08b86ddb57.css → 3d6582469f7d56e0.css} +1 -1
- fides/ui-build/static/admin/_next/static/css/3d66bb57ddcb0978.css +1 -0
- fides/ui-build/static/admin/_next/static/css/4861ca3e088f2d05.css +1 -0
- fides/ui-build/static/admin/_next/static/css/a1800714b486e230.css +1 -0
- fides/ui-build/static/admin/_next/static/css/a1e4be9466578ef1.css +1 -0
- fides/ui-build/static/admin/_next/static/css/af32fcac7a177a0e.css +1 -0
- fides/ui-build/static/admin/_next/static/css/cb417f0587918f85.css +1 -0
- fides/ui-build/static/admin/_next/static/css/dd15c278b964de80.css +1 -0
- fides/ui-build/static/admin/_next/static/css/{5f393dea1c0d031c.css → f89607996ad54f4b.css} +1 -1
- fides/ui-build/static/admin/_next/static/css/f9a2a44d3d34c904.css +1 -0
- fides/ui-build/static/admin/_next/static/l2vgGUHB04Fi4oEVlVMrc/_buildManifest.js +1 -0
- fides/ui-build/static/admin/add-systems/manual.html +1 -1
- fides/ui-build/static/admin/add-systems/multiple.html +1 -1
- fides/ui-build/static/admin/add-systems.html +1 -1
- fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
- fides/ui-build/static/admin/consent/configure.html +1 -1
- fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
- fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
- fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
- fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
- fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
- fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
- fides/ui-build/static/admin/consent/properties.html +1 -1
- fides/ui-build/static/admin/consent/reporting.html +1 -1
- fides/ui-build/static/admin/consent.html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
- fides/ui-build/static/admin/data-catalog.html +1 -1
- fides/ui-build/static/admin/data-discovery/action-center/datastore/[monitorId].html +1 -0
- fides/ui-build/static/admin/data-discovery/action-center/datastore.html +1 -0
- fides/ui-build/static/admin/data-discovery/action-center/infrastructure/[monitorId].html +1 -0
- fides/ui-build/static/admin/data-discovery/action-center/infrastructure.html +1 -0
- fides/ui-build/static/admin/data-discovery/action-center/website/[monitorId]/[systemId].html +1 -0
- fides/ui-build/static/admin/data-discovery/action-center/website/[monitorId].html +1 -0
- fides/ui-build/static/admin/data-discovery/action-center/website.html +1 -0
- fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
- fides/ui-build/static/admin/data-discovery/activity.html +1 -1
- fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-discovery/detection.html +1 -1
- fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
- fides/ui-build/static/admin/datamap.html +1 -1
- fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
- fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
- fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
- fides/ui-build/static/admin/dataset/new.html +1 -1
- fides/ui-build/static/admin/dataset.html +1 -1
- fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
- fides/ui-build/static/admin/datastore-connection/new.html +1 -1
- fides/ui-build/static/admin/datastore-connection.html +1 -1
- fides/ui-build/static/admin/index.html +1 -1
- fides/ui-build/static/admin/integrations/[id].html +1 -1
- fides/ui-build/static/admin/integrations.html +1 -1
- fides/ui-build/static/admin/lib/fides-ext-gpp.js +1 -1
- fides/ui-build/static/admin/lib/fides-headless.js +1 -1
- fides/ui-build/static/admin/lib/fides-preview.js +1 -1
- fides/ui-build/static/admin/lib/fides-tcf.js +3 -3
- fides/ui-build/static/admin/lib/fides.js +3 -3
- fides/ui-build/static/admin/login/[provider].html +1 -1
- fides/ui-build/static/admin/login.html +1 -1
- fides/ui-build/static/admin/new-privacy-requests.html +1 -0
- fides/ui-build/static/admin/notifications/digests/[id].html +1 -0
- fides/ui-build/static/admin/notifications/digests/new.html +1 -0
- fides/ui-build/static/admin/notifications/digests.html +1 -0
- fides/ui-build/static/admin/notifications/providers/[key].html +1 -0
- fides/ui-build/static/admin/notifications/providers/new.html +1 -0
- fides/ui-build/static/admin/notifications/providers.html +1 -0
- fides/ui-build/static/admin/notifications/templates/[id].html +1 -0
- fides/ui-build/static/admin/notifications/templates/add-template.html +1 -0
- fides/ui-build/static/admin/notifications/templates.html +1 -0
- fides/ui-build/static/admin/notifications.html +1 -0
- fides/ui-build/static/admin/poc/ant-components.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/AntForm.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikAntFormItem.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikControlled.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikField.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikSpreadField.html +1 -1
- fides/ui-build/static/admin/poc/forms.html +1 -1
- fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
- fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
- fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
- fides/ui-build/static/admin/privacy-requests.html +1 -1
- fides/ui-build/static/admin/properties/[id].html +1 -1
- fides/ui-build/static/admin/properties/add-property.html +1 -1
- fides/ui-build/static/admin/properties.html +1 -1
- fides/ui-build/static/admin/reporting/datamap.html +1 -1
- fides/ui-build/static/admin/sandbox/privacy-notices.html +1 -0
- fides/ui-build/static/admin/settings/about/alpha.html +1 -1
- fides/ui-build/static/admin/settings/about.html +1 -1
- fides/ui-build/static/admin/settings/consent/[configuration_id]/[purpose_id].html +1 -1
- fides/ui-build/static/admin/settings/consent.html +1 -1
- fides/ui-build/static/admin/settings/custom-fields/[id].html +1 -0
- fides/ui-build/static/admin/settings/custom-fields/new.html +1 -0
- fides/ui-build/static/admin/settings/custom-fields.html +1 -1
- fides/ui-build/static/admin/settings/domain-records.html +1 -1
- fides/ui-build/static/admin/settings/domains.html +1 -1
- fides/ui-build/static/admin/settings/email-templates.html +1 -1
- fides/ui-build/static/admin/settings/locations.html +1 -1
- fides/ui-build/static/admin/settings/organization.html +1 -1
- fides/ui-build/static/admin/settings/privacy-requests.html +1 -1
- fides/ui-build/static/admin/settings/regulations.html +1 -1
- fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
- fides/ui-build/static/admin/systems/configure/[id].html +1 -1
- fides/ui-build/static/admin/systems.html +1 -1
- fides/ui-build/static/admin/taxonomy.html +1 -1
- fides/ui-build/static/admin/user-management/new.html +1 -1
- fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
- fides/ui-build/static/admin/user-management.html +1 -1
- fides/api/service/async_dsr/async_dsr_service.py +0 -75
- fides/api/service/privacy_request/dsr_package/templates/welcome.html +0 -66
- fides/ui-build/static/admin/_next/static/OmXHlY9MvjoZH9jDkAytl/_buildManifest.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1099-79646e64f26d62fa.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1316-2606e19807c08aa5.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1345-5e1c5b66e25c566e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1467-8808ec8836e033f9.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1817-0ca16d288fad916d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/2150-930ffaf2c4718edc.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/255-1bc0cbef7a59cdc6.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/2921-52328140bc420d0f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/346-aa3b88efb85f2e28.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3550-d04125c828d591a1.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3620-602eb74dc896d556.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3729-c17ac8031a4c4fd1.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3847-230bf61b053bc706.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3855-ef5194cdb228beb6.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3872-f78dec02f0d959ae.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3923-bb2417b8dcade7a4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/401-4af0a912e249d30f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4164-355644b916ae0094.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/431-86ad2beeb93c95c9.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4608-be8cba73f5d7c326.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4786-61154adf88e448e1.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4808-dd4157aa72648068.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4831-fd99c0b3784de128.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4844-46324c3d848b8b6a.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5163-e682273cd76a7d07.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5258-b0de22a8521686ab.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5487-02d00bad7c6830e0.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/549-38ea1d91ee2addaa.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5619-9b50cec521203989.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6084-c153669d5567e242.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6419-d0c00d661b01f8fa.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6853-b17673391117c976.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6954-5296188c19d7d0ac.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/699-8ca44b0de9fa20f0.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/7476-45c5088baa8b66af.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/7630-7ed6c6117775dffe.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/787-a8c7eab617e2fceb.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/79-65674011d455af4d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/796-9e1ca1a4030707c5.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/8002-24af20d679efc04e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/8765-f622a35b40a7ec63.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9046-712156d461165f56.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9187-7438242f0d380bb0.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9278-08cc704317fe535e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9729-fcf6ff4e3534e4a8.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9826-dbae8dee941a7fac.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9951-a88367a129b724ba.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/manual-ace203dfacacbdc4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/multiple-920fb469e0dda1d2.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-bd0d82078e67cac3.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-7207ab23bdb36ce8.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience-9dda4de5ec580279.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-0d4844d0b808e6e4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-28b192e2c074b0f3.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent-3e8bdefe714254ec.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn]-2c29ff7a01198f30.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-5f2d7b24804f861f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/[resourceUrn]-8eb581024bc0172f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-30108b00ac769fc3.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-e1ba213fb666b3f4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-6d133580045abdda.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-9a81d42a474e1e48.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-b6ae7adb8ef0b525.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datamap-c7390e046b2e2b7f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-e12b11ba15bc3fc1.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-e32fccc4ca520d2b.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset-7c59a6abf6ba6207.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/[id]-927b7e476c4b47d0.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-cbe100d50df34285.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-cce20440b177050b.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/index-6cd8708106331b8d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-4c3c413a2668df53.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations-95402b5001c07ef2.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/messaging/[id]-3c6dc2f6e6bae960.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/messaging/add-template-4a6d4023a7791be8.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/messaging-76b204c9b98d656f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-bc0e2adf6e0d3ac7.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/AntForm-86ffcc1ad3fa912e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikAntFormItem-ec04f595465bdf69.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikControlled-41d309754ff0c1de.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikField-cab1f78cec7808f9.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/forms-eb6058221403b156.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/table-migration-48500551fd6a7602.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-0f25a76dd18c5e20.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-ad6ad3e5bd72765d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-6032d82f0fc2893d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure-d83e5bd52a638234.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-baf31c3e4b081046.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-6903f42a0412bfa6.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/alpha-a82f3df840d5c1b5.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/about-d06fb16487705b9d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-9495e2eb506606c7.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-93a978443bf299db.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-9ecb803099082bf4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/domain-records-16fdd91a81074dd1.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-4cdd6001e7cb9aee.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/email-templates-1914de830ce5cfc4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-f547f1f33c12faf3.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/privacy-requests-2ecc073f41628f62.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-20b1193ed76c56b0.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]-6e15332935f6b538.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems-fbc8761ef4d55516.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-4d7827fc9c46b6b8.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management-9cec020f89544426.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/webpack-678e89d68dbcd94f.js +0 -1
- fides/ui-build/static/admin/_next/static/css/073713cd1eddda79.css +0 -1
- fides/ui-build/static/admin/_next/static/css/23cf870196941c9a.css +0 -1
- fides/ui-build/static/admin/_next/static/css/304c6f148886a8d4.css +0 -1
- fides/ui-build/static/admin/_next/static/css/650df9c348000a26.css +0 -1
- fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/[systemId].html +0 -1
- fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +0 -1
- fides/ui-build/static/admin/messaging/[id].html +0 -1
- fides/ui-build/static/admin/messaging/add-template.html +0 -1
- fides/ui-build/static/admin/messaging.html +0 -1
- fides/ui-build/static/admin/poc/table-migration.html +0 -1
- fides/ui-build/static/admin/privacy-requests/configure/messaging.html +0 -1
- {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/WHEEL +0 -0
- {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/entry_points.txt +0 -0
- {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/licenses/LICENSE +0 -0
- {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/top_level.txt +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{resources-de704de849960f01.js → resources-81d1b50585468fb0.js} +0 -0
- /fides/ui-build/static/admin/_next/static/{OmXHlY9MvjoZH9jDkAytl → l2vgGUHB04Fi4oEVlVMrc}/_ssgManifest.js +0 -0
|
@@ -3,11 +3,13 @@ from __future__ import annotations
|
|
|
3
3
|
|
|
4
4
|
import csv
|
|
5
5
|
import json
|
|
6
|
+
import time
|
|
7
|
+
from copy import deepcopy
|
|
6
8
|
from datetime import datetime
|
|
7
9
|
from io import BytesIO, StringIO
|
|
8
10
|
from itertools import chain
|
|
9
11
|
from typing import Any, Generator, Iterable, Optional, Tuple
|
|
10
|
-
from urllib.parse import urlparse
|
|
12
|
+
from urllib.parse import unquote, urlparse
|
|
11
13
|
|
|
12
14
|
from fideslang.validation import AnyHttpUrlString
|
|
13
15
|
from loguru import logger
|
|
@@ -25,22 +27,21 @@ from fides.api.service.storage.streaming.dsr_storage import (
|
|
|
25
27
|
)
|
|
26
28
|
from fides.api.service.storage.streaming.retry import retry_cloud_storage_operation
|
|
27
29
|
from fides.api.service.storage.streaming.schemas import (
|
|
28
|
-
|
|
30
|
+
DEFAULT_CHUNK_SIZE,
|
|
31
|
+
MAX_FILE_SIZE,
|
|
29
32
|
AttachmentInfo,
|
|
30
33
|
AttachmentProcessingInfo,
|
|
31
|
-
|
|
34
|
+
SmartOpenStreamingStorageConfig,
|
|
32
35
|
StorageUploadConfig,
|
|
33
36
|
StreamingBufferConfig,
|
|
34
37
|
)
|
|
35
38
|
from fides.api.service.storage.streaming.smart_open_client import SmartOpenStorageClient
|
|
36
39
|
from fides.api.service.storage.util import (
|
|
37
|
-
convert_processed_attachments_to_attachment_processing_info,
|
|
38
40
|
determine_dataset_name_from_path,
|
|
39
|
-
extract_storage_key_from_attachment,
|
|
40
41
|
get_unique_filename,
|
|
41
42
|
process_attachments_contextually,
|
|
42
43
|
resolve_attachment_storage_path,
|
|
43
|
-
|
|
44
|
+
resolve_path_from_context,
|
|
44
45
|
)
|
|
45
46
|
|
|
46
47
|
DEFAULT_ATTACHMENT_NAME = "attachment"
|
|
@@ -66,16 +67,22 @@ class SmartOpenStreamingStorage:
|
|
|
66
67
|
def __init__(
|
|
67
68
|
self,
|
|
68
69
|
storage_client: SmartOpenStorageClient,
|
|
69
|
-
chunk_size: int =
|
|
70
|
+
chunk_size: int = DEFAULT_CHUNK_SIZE,
|
|
70
71
|
):
|
|
71
72
|
"""Initialize with a smart-open storage client.
|
|
72
73
|
|
|
73
74
|
Args:
|
|
74
75
|
storage_client: Smart-open based storage client
|
|
75
|
-
chunk_size: Size of chunks for streaming attachments (default:
|
|
76
|
+
chunk_size: Size of chunks for streaming attachments (default: 5MB)
|
|
77
|
+
|
|
78
|
+
Raises:
|
|
79
|
+
ValidationError: If chunk_size is outside valid range (1KB - 2GB)
|
|
76
80
|
"""
|
|
81
|
+
# Validate parameters using Pydantic schema
|
|
82
|
+
config = SmartOpenStreamingStorageConfig(chunk_size=chunk_size)
|
|
83
|
+
|
|
77
84
|
self.storage_client = storage_client
|
|
78
|
-
self.chunk_size = chunk_size
|
|
85
|
+
self.chunk_size = config.chunk_size
|
|
79
86
|
# Track used filenames per dataset to match DSR report builder behavior
|
|
80
87
|
# Maps dataset_name -> set of used filenames
|
|
81
88
|
self.used_filenames_per_dataset: dict[str, set[str]] = {}
|
|
@@ -98,10 +105,15 @@ class SmartOpenStreamingStorage:
|
|
|
98
105
|
Raises:
|
|
99
106
|
ValueError: If URL cannot be parsed
|
|
100
107
|
"""
|
|
108
|
+
if storage_key is None or storage_key == "":
|
|
109
|
+
logger.error(f"Storage key cannot be empty: {storage_key}")
|
|
110
|
+
raise ValueError("Storage key cannot be empty")
|
|
111
|
+
|
|
101
112
|
if storage_key.startswith("s3://"):
|
|
102
113
|
# Extract bucket from S3 URL: s3://bucket/path
|
|
103
114
|
parts = storage_key.split("/")
|
|
104
115
|
if len(parts) < 4:
|
|
116
|
+
logger.error(f"Invalid S3 URL format: {storage_key}")
|
|
105
117
|
raise ValueError(f"Invalid S3 URL format: {storage_key}")
|
|
106
118
|
return parts[2], "/".join(parts[3:])
|
|
107
119
|
|
|
@@ -111,16 +123,16 @@ class SmartOpenStreamingStorage:
|
|
|
111
123
|
parts = clean_url.split(S3_AMAZONAWS_COM_DOMAIN)
|
|
112
124
|
if len(parts) == 2:
|
|
113
125
|
bucket = parts[0].replace("https://", "").replace("http://", "")
|
|
114
|
-
key =
|
|
115
|
-
"/"
|
|
116
|
-
) #
|
|
126
|
+
key = unquote(
|
|
127
|
+
parts[1].lstrip("/")
|
|
128
|
+
) # URL-decode and strip leading slash for S3 compatibility
|
|
117
129
|
return bucket, key
|
|
118
130
|
|
|
119
131
|
# Handle generic HTTP(S) URLs
|
|
120
132
|
if storage_key.startswith(("http://", "https://")):
|
|
121
133
|
parsed = urlparse(storage_key)
|
|
122
134
|
bucket = parsed.netloc
|
|
123
|
-
key = parsed.path.lstrip("/")
|
|
135
|
+
key = unquote(parsed.path.lstrip("/")) # URL-decode the path
|
|
124
136
|
return bucket, key
|
|
125
137
|
|
|
126
138
|
raise ValueError(f"Could not parse storage URL: {storage_key}")
|
|
@@ -143,103 +155,6 @@ class SmartOpenStreamingStorage:
|
|
|
143
155
|
[content_bytes]
|
|
144
156
|
)
|
|
145
157
|
|
|
146
|
-
def build_attachments_list(
|
|
147
|
-
self, data: dict, config: PackageSplitConfig
|
|
148
|
-
) -> list[tuple[str, dict, int]]:
|
|
149
|
-
"""
|
|
150
|
-
Build a list of attachments from the data.
|
|
151
|
-
|
|
152
|
-
Args:
|
|
153
|
-
data: The data to build the attachments list from
|
|
154
|
-
config: The configuration for package splitting
|
|
155
|
-
|
|
156
|
-
Returns:
|
|
157
|
-
A list of AttachmentInfo objects
|
|
158
|
-
"""
|
|
159
|
-
attachments_list = []
|
|
160
|
-
for key, value in data.items():
|
|
161
|
-
if not isinstance(value, list):
|
|
162
|
-
continue
|
|
163
|
-
|
|
164
|
-
for item in value:
|
|
165
|
-
attachments = item.get("attachments", [])
|
|
166
|
-
if not isinstance(attachments, list):
|
|
167
|
-
attachments = []
|
|
168
|
-
|
|
169
|
-
attachment_count = len(attachments)
|
|
170
|
-
|
|
171
|
-
# Only include items that have attachments
|
|
172
|
-
if attachment_count > 0:
|
|
173
|
-
# If a single item has more attachments than the limit, we need to split it
|
|
174
|
-
if attachment_count > config.max_attachments:
|
|
175
|
-
# Split the item into multiple sub-items
|
|
176
|
-
for i in range(0, attachment_count, config.max_attachments):
|
|
177
|
-
sub_attachments = attachments[
|
|
178
|
-
i : i + config.max_attachments
|
|
179
|
-
]
|
|
180
|
-
sub_item = item.copy()
|
|
181
|
-
sub_item["attachments"] = sub_attachments
|
|
182
|
-
attachments_list.append(
|
|
183
|
-
(key, sub_item, len(sub_attachments))
|
|
184
|
-
)
|
|
185
|
-
else:
|
|
186
|
-
attachments_list.append((key, item, attachment_count))
|
|
187
|
-
|
|
188
|
-
return attachments_list
|
|
189
|
-
|
|
190
|
-
def split_data_into_packages(
|
|
191
|
-
self, data: dict, config: Optional[PackageSplitConfig] = None
|
|
192
|
-
) -> list[dict]:
|
|
193
|
-
"""Split large datasets into multiple smaller packages.
|
|
194
|
-
|
|
195
|
-
Uses a best-fit decreasing algorithm to optimize package distribution:
|
|
196
|
-
1. Sort items by attachment count (largest first)
|
|
197
|
-
2. Try to fit each item in the package with the most remaining space
|
|
198
|
-
3. Create new packages only when necessary
|
|
199
|
-
4. Handle items that exceed the max_attachments limit by splitting them
|
|
200
|
-
|
|
201
|
-
Args:
|
|
202
|
-
data: The data to split
|
|
203
|
-
config: Configuration for package splitting (defaults to PackageSplitConfig())
|
|
204
|
-
|
|
205
|
-
Returns:
|
|
206
|
-
List of data packages
|
|
207
|
-
"""
|
|
208
|
-
# Use default config if none provided
|
|
209
|
-
if config is None:
|
|
210
|
-
config = PackageSplitConfig()
|
|
211
|
-
|
|
212
|
-
# Collect all items with their attachment counts
|
|
213
|
-
all_items = self.build_attachments_list(data, config)
|
|
214
|
-
|
|
215
|
-
# Sort by attachment count (largest first) for better space utilization
|
|
216
|
-
all_items.sort(key=lambda x: x[2], reverse=True)
|
|
217
|
-
|
|
218
|
-
packages: list[dict[str, Any]] = []
|
|
219
|
-
package_attachment_counts: list[int] = []
|
|
220
|
-
|
|
221
|
-
for key, item, attachment_count in all_items:
|
|
222
|
-
# Try to find a package with enough space
|
|
223
|
-
package_found = False
|
|
224
|
-
|
|
225
|
-
for i, current_count in enumerate(package_attachment_counts):
|
|
226
|
-
if current_count + attachment_count <= config.max_attachments:
|
|
227
|
-
# Add to existing package
|
|
228
|
-
if key not in packages[i]:
|
|
229
|
-
packages[i][key] = []
|
|
230
|
-
packages[i][key].append(item)
|
|
231
|
-
package_attachment_counts[i] += attachment_count
|
|
232
|
-
package_found = True
|
|
233
|
-
break
|
|
234
|
-
|
|
235
|
-
if not package_found:
|
|
236
|
-
# Create new package - this item cannot fit in any existing package
|
|
237
|
-
new_package = {key: [item]}
|
|
238
|
-
packages.append(new_package)
|
|
239
|
-
package_attachment_counts.append(attachment_count)
|
|
240
|
-
|
|
241
|
-
return packages
|
|
242
|
-
|
|
243
158
|
def _validate_attachment(
|
|
244
159
|
self, attachment: dict
|
|
245
160
|
) -> Optional[AttachmentProcessingInfo]:
|
|
@@ -253,7 +168,9 @@ class SmartOpenStreamingStorage:
|
|
|
253
168
|
"""
|
|
254
169
|
try:
|
|
255
170
|
# Extract storage key using shared utility
|
|
256
|
-
storage_key =
|
|
171
|
+
storage_key = (
|
|
172
|
+
attachment.get("download_url") or attachment.get("file_name") or ""
|
|
173
|
+
)
|
|
257
174
|
if not storage_key:
|
|
258
175
|
return None
|
|
259
176
|
|
|
@@ -266,7 +183,7 @@ class SmartOpenStreamingStorage:
|
|
|
266
183
|
)
|
|
267
184
|
|
|
268
185
|
# Resolve base path using shared utility
|
|
269
|
-
base_path =
|
|
186
|
+
base_path = resolve_path_from_context(attachment)
|
|
270
187
|
|
|
271
188
|
# Create AttachmentProcessingInfo
|
|
272
189
|
processing_info = AttachmentProcessingInfo(
|
|
@@ -294,26 +211,82 @@ class SmartOpenStreamingStorage:
|
|
|
294
211
|
Returns:
|
|
295
212
|
Iterator that yields chunks of the attachment content
|
|
296
213
|
"""
|
|
214
|
+
for arg in [bucket, key, storage_key]:
|
|
215
|
+
if arg is None or arg == "":
|
|
216
|
+
logger.error(f"{arg} cannot be empty: {arg}")
|
|
217
|
+
raise ValueError(f"{arg} cannot be empty")
|
|
218
|
+
|
|
297
219
|
try:
|
|
298
220
|
with self.storage_client.stream_read(bucket, key) as content_stream:
|
|
299
221
|
# Stream in chunks instead of reading entire file
|
|
300
|
-
chunk_count = 0
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
222
|
+
chunk_count = total_bytes = 0
|
|
223
|
+
max_chunks = (
|
|
224
|
+
MAX_FILE_SIZE // self.chunk_size + 1
|
|
225
|
+
) # Safety limit to prevent infinite loops
|
|
226
|
+
|
|
227
|
+
size_based_timeout = MAX_FILE_SIZE // (10 * 1024 * 1024) # 1s per 10MB
|
|
228
|
+
timeout = 300 + size_based_timeout # 5 minutes base + 1s per 10MB
|
|
229
|
+
start_time = time.time()
|
|
230
|
+
|
|
231
|
+
# Log the calculated timeout for debugging
|
|
232
|
+
logger.debug(
|
|
233
|
+
f"Starting stream for {storage_key} with timeout: {timeout}s "
|
|
234
|
+
f"(base: 300s + size-based: {size_based_timeout}s)"
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
while chunk_count < max_chunks and total_bytes < MAX_FILE_SIZE:
|
|
238
|
+
elapsed_time = time.time() - start_time
|
|
239
|
+
if elapsed_time >= timeout:
|
|
240
|
+
raise TimeoutError(
|
|
241
|
+
f"Timeout reached ({timeout}s) while streaming attachment {storage_key}."
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
try:
|
|
245
|
+
chunk = content_stream.read(self.chunk_size)
|
|
246
|
+
except Exception as read_error:
|
|
247
|
+
logger.error(
|
|
248
|
+
f"Error reading chunk from stream for {storage_key}: {read_error}"
|
|
249
|
+
)
|
|
250
|
+
raise StorageUploadError(
|
|
251
|
+
f"Stream read error for {storage_key}: {read_error}"
|
|
252
|
+
) from read_error
|
|
253
|
+
|
|
304
254
|
if not chunk:
|
|
255
|
+
# End of stream reached normally
|
|
256
|
+
logger.debug(
|
|
257
|
+
f"Successfully streamed attachment {storage_key}: "
|
|
258
|
+
f"{total_bytes} bytes in {chunk_count} chunks"
|
|
259
|
+
)
|
|
305
260
|
break
|
|
261
|
+
|
|
306
262
|
chunk_count += 1
|
|
307
263
|
total_bytes += len(chunk)
|
|
308
264
|
yield chunk
|
|
309
265
|
|
|
266
|
+
# Log if we hit limits
|
|
267
|
+
if chunk_count >= max_chunks:
|
|
268
|
+
logger.warning(
|
|
269
|
+
f"Maximum chunk count ({max_chunks}) reached for attachment {storage_key}. "
|
|
270
|
+
f"Streamed {total_bytes} bytes. Stream may be incomplete."
|
|
271
|
+
)
|
|
272
|
+
elif total_bytes >= MAX_FILE_SIZE:
|
|
273
|
+
logger.warning(
|
|
274
|
+
f"Maximum file size ({MAX_FILE_SIZE} bytes) reached for attachment {storage_key}. "
|
|
275
|
+
f"Streamed {total_bytes} bytes in {chunk_count} chunks. Stream may be incomplete."
|
|
276
|
+
)
|
|
277
|
+
|
|
310
278
|
except Exception as e:
|
|
311
|
-
logger.
|
|
312
|
-
|
|
313
|
-
|
|
279
|
+
logger.error(f"Failed to stream attachment {storage_key}: {e}")
|
|
280
|
+
raise StorageUploadError(
|
|
281
|
+
f"Failed to stream attachment {storage_key}: {e}"
|
|
282
|
+
) from e
|
|
314
283
|
|
|
315
284
|
def _collect_and_validate_attachments(
|
|
316
|
-
self,
|
|
285
|
+
self,
|
|
286
|
+
data: dict,
|
|
287
|
+
used_filenames_data: set[str],
|
|
288
|
+
used_filenames_attachments: set[str],
|
|
289
|
+
processed_attachments: dict[tuple[str, str], str],
|
|
317
290
|
) -> list[AttachmentProcessingInfo]:
|
|
318
291
|
"""Collect and validate attachments using the same contextual approach as DSR report builder.
|
|
319
292
|
|
|
@@ -326,24 +299,30 @@ class SmartOpenStreamingStorage:
|
|
|
326
299
|
Returns:
|
|
327
300
|
List of validated AttachmentProcessingInfo objects
|
|
328
301
|
"""
|
|
329
|
-
|
|
330
|
-
used_filenames_data: set[str] = set()
|
|
331
|
-
used_filenames_attachments: set[str] = set()
|
|
332
|
-
processed_attachments: dict[tuple[str, str], str] = {}
|
|
302
|
+
validated_attachments = []
|
|
333
303
|
|
|
334
304
|
# Use the shared contextual processing function
|
|
305
|
+
# Note: This method should only be used when DSR report builder is not available
|
|
306
|
+
# For HTML format, use _collect_and_validate_attachments_from_dsr_builder instead
|
|
335
307
|
processed_attachments_list = process_attachments_contextually(
|
|
336
|
-
data,
|
|
337
|
-
used_filenames_data,
|
|
338
|
-
used_filenames_attachments,
|
|
339
|
-
processed_attachments,
|
|
340
|
-
enable_streaming=True,
|
|
308
|
+
data=data,
|
|
309
|
+
used_filenames_data=used_filenames_data,
|
|
310
|
+
used_filenames_attachments=used_filenames_attachments,
|
|
311
|
+
processed_attachments=processed_attachments,
|
|
312
|
+
enable_streaming=True,
|
|
341
313
|
)
|
|
342
314
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
315
|
+
for processed_attachment in processed_attachments_list:
|
|
316
|
+
# Add context information to the attachment data
|
|
317
|
+
attachment_with_context = deepcopy(processed_attachment["attachment"])
|
|
318
|
+
attachment_with_context["_context"] = processed_attachment["context"]
|
|
319
|
+
|
|
320
|
+
# Validate and convert to AttachmentProcessingInfo
|
|
321
|
+
validated = self._validate_attachment(attachment_with_context)
|
|
322
|
+
if validated:
|
|
323
|
+
validated_attachments.append(validated)
|
|
324
|
+
|
|
325
|
+
return validated_attachments
|
|
347
326
|
|
|
348
327
|
def _collect_and_validate_attachments_from_dsr_builder(
|
|
349
328
|
self, data: dict, dsr_builder: "DSRReportBuilder"
|
|
@@ -372,17 +351,11 @@ class SmartOpenStreamingStorage:
|
|
|
372
351
|
else:
|
|
373
352
|
used_filenames_data.update(filenames)
|
|
374
353
|
|
|
375
|
-
|
|
354
|
+
return self._collect_and_validate_attachments(
|
|
376
355
|
data,
|
|
377
356
|
used_filenames_data,
|
|
378
357
|
used_filenames_attachments,
|
|
379
358
|
dsr_builder.processed_attachments,
|
|
380
|
-
enable_streaming=True, # Always use streaming mode for storage
|
|
381
|
-
)
|
|
382
|
-
|
|
383
|
-
# Convert to AttachmentProcessingInfo objects using shared utility
|
|
384
|
-
return convert_processed_attachments_to_attachment_processing_info(
|
|
385
|
-
processed_attachments_list, self._validate_attachment
|
|
386
359
|
)
|
|
387
360
|
|
|
388
361
|
@retry_cloud_storage_operation(
|
|
@@ -404,7 +377,7 @@ class SmartOpenStreamingStorage:
|
|
|
404
377
|
"""Upload data to cloud storage using smart-open streaming for memory efficiency.
|
|
405
378
|
|
|
406
379
|
This function leverages smart-open's streaming capabilities while maintaining
|
|
407
|
-
our DSR-specific business logic for package
|
|
380
|
+
our DSR-specific business logic for package and attachment processing.
|
|
408
381
|
All data is streamed directly from source to destination without local storage.
|
|
409
382
|
|
|
410
383
|
Args:
|
|
@@ -557,8 +530,9 @@ class SmartOpenStreamingStorage:
|
|
|
557
530
|
raise StorageUploadError(f"Failed to generate DSR report: {e}") from e
|
|
558
531
|
|
|
559
532
|
# Use the DSR report builder's processed attachments to avoid duplicates
|
|
533
|
+
# Use the redacted data from the DSR report builder instead of the original data
|
|
560
534
|
all_attachments = self._collect_and_validate_attachments_from_dsr_builder(
|
|
561
|
-
|
|
535
|
+
dsr_builder.dsr_data, dsr_builder
|
|
562
536
|
)
|
|
563
537
|
|
|
564
538
|
if not all_attachments:
|
|
@@ -595,7 +569,9 @@ class SmartOpenStreamingStorage:
|
|
|
595
569
|
)
|
|
596
570
|
|
|
597
571
|
# Create ZIP generator with attachment files
|
|
598
|
-
attachment_files_generator = self._create_attachment_files(
|
|
572
|
+
attachment_files_generator = self._create_attachment_files(
|
|
573
|
+
all_attachments, buffer_config
|
|
574
|
+
)
|
|
599
575
|
|
|
600
576
|
# Combine both generators and stream the complete ZIP to storage
|
|
601
577
|
combined_entries = chain(attachment_files_generator, dsr_files_generator)
|
|
@@ -654,7 +630,12 @@ class SmartOpenStreamingStorage:
|
|
|
654
630
|
resp_format: Response format (csv, json)
|
|
655
631
|
"""
|
|
656
632
|
# Collect and validate all attachments using shared contextual processing
|
|
657
|
-
all_attachments = self._collect_and_validate_attachments(
|
|
633
|
+
all_attachments = self._collect_and_validate_attachments(
|
|
634
|
+
data=data,
|
|
635
|
+
used_filenames_data=set(),
|
|
636
|
+
used_filenames_attachments=set(),
|
|
637
|
+
processed_attachments={},
|
|
638
|
+
)
|
|
658
639
|
|
|
659
640
|
if not all_attachments:
|
|
660
641
|
# No attachments, just upload the data
|
|
@@ -673,6 +654,7 @@ class SmartOpenStreamingStorage:
|
|
|
673
654
|
max_workers,
|
|
674
655
|
batch_size,
|
|
675
656
|
resp_format,
|
|
657
|
+
buffer_config,
|
|
676
658
|
)
|
|
677
659
|
|
|
678
660
|
# Use smart-open's streaming upload capability
|
|
@@ -718,6 +700,7 @@ class SmartOpenStreamingStorage:
|
|
|
718
700
|
max_workers: int,
|
|
719
701
|
batch_size: int,
|
|
720
702
|
resp_format: str,
|
|
703
|
+
buffer_config: Optional[StreamingBufferConfig] = None,
|
|
721
704
|
) -> Generator[Tuple[str, datetime, int, Any, Iterable[bytes]], None, None]:
|
|
722
705
|
"""Create a generator for ZIP file contents including data and attachments.
|
|
723
706
|
|
|
@@ -743,7 +726,9 @@ class SmartOpenStreamingStorage:
|
|
|
743
726
|
yield from self._convert_to_stream_zip_format(data_files_generator)
|
|
744
727
|
|
|
745
728
|
# Then, yield attachment files (already in stream_zip format, stream directly)
|
|
746
|
-
attachment_files_generator = self._create_attachment_files(
|
|
729
|
+
attachment_files_generator = self._create_attachment_files(
|
|
730
|
+
all_attachments, buffer_config
|
|
731
|
+
)
|
|
747
732
|
yield from attachment_files_generator
|
|
748
733
|
|
|
749
734
|
def _create_data_files(
|
|
@@ -785,9 +770,62 @@ class SmartOpenStreamingStorage:
|
|
|
785
770
|
data_content = json.dumps(value, default=str).encode("utf-8")
|
|
786
771
|
yield f"{key}.json", BytesIO(data_content), {}
|
|
787
772
|
|
|
773
|
+
def _handle_attachment_error(
|
|
774
|
+
self,
|
|
775
|
+
all_attachments: list[AttachmentProcessingInfo],
|
|
776
|
+
failed_attachments: list[dict[str, Optional[str]]],
|
|
777
|
+
) -> Generator[Tuple[str, datetime, int, Any, Iterable[bytes]], None, None]:
|
|
778
|
+
"""Handle attachment errors and create a summary file."""
|
|
779
|
+
|
|
780
|
+
try:
|
|
781
|
+
# Calculate success rate with division by zero protection
|
|
782
|
+
total_attempted = len(all_attachments)
|
|
783
|
+
total_failed = len(failed_attachments)
|
|
784
|
+
success_rate = "N/A"
|
|
785
|
+
|
|
786
|
+
if total_attempted > 0:
|
|
787
|
+
success_rate = (
|
|
788
|
+
f"{((total_attempted - total_failed) / total_attempted * 100):.1f}%"
|
|
789
|
+
)
|
|
790
|
+
|
|
791
|
+
error_summary = {
|
|
792
|
+
"failed_attachments": failed_attachments,
|
|
793
|
+
"total_failed": total_failed,
|
|
794
|
+
"total_attempted": total_attempted,
|
|
795
|
+
"success_rate": success_rate,
|
|
796
|
+
"timestamp": datetime.now().isoformat(),
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
error_summary_content = json.dumps(error_summary, indent=2).encode("utf-8")
|
|
800
|
+
yield (
|
|
801
|
+
"errors/attachment_failures_summary.json",
|
|
802
|
+
datetime.now(),
|
|
803
|
+
DEFAULT_FILE_MODE,
|
|
804
|
+
_ZIP_32_TYPE(),
|
|
805
|
+
iter([error_summary_content]),
|
|
806
|
+
)
|
|
807
|
+
except Exception as summary_error:
|
|
808
|
+
logger.error(f"Failed to create error summary: {summary_error}")
|
|
809
|
+
# Create a minimal error summary as fallback
|
|
810
|
+
fallback_summary = {
|
|
811
|
+
"error": "Failed to generate detailed error summary",
|
|
812
|
+
"total_failed": len(failed_attachments),
|
|
813
|
+
"total_attempted": len(all_attachments),
|
|
814
|
+
"timestamp": datetime.now().isoformat(),
|
|
815
|
+
}
|
|
816
|
+
fallback_content = json.dumps(fallback_summary, indent=2).encode("utf-8")
|
|
817
|
+
yield (
|
|
818
|
+
"errors/attachment_failures_summary.json",
|
|
819
|
+
datetime.now(),
|
|
820
|
+
DEFAULT_FILE_MODE,
|
|
821
|
+
_ZIP_32_TYPE(),
|
|
822
|
+
iter([fallback_content]),
|
|
823
|
+
)
|
|
824
|
+
|
|
788
825
|
def _create_attachment_files(
|
|
789
826
|
self,
|
|
790
827
|
all_attachments: list[AttachmentProcessingInfo],
|
|
828
|
+
buffer_config: Optional[StreamingBufferConfig] = None,
|
|
791
829
|
) -> Generator[Tuple[str, datetime, int, Any, Iterable[bytes]], None, None]:
|
|
792
830
|
"""Create attachment files for the ZIP using true cloud-to-cloud streaming.
|
|
793
831
|
|
|
@@ -797,13 +835,66 @@ class SmartOpenStreamingStorage:
|
|
|
797
835
|
|
|
798
836
|
Args:
|
|
799
837
|
all_attachments: List of validated attachments
|
|
838
|
+
buffer_config: Configuration for error handling behavior
|
|
800
839
|
|
|
801
840
|
Returns:
|
|
802
841
|
Generator yielding attachment file entries in stream_zip format
|
|
803
842
|
"""
|
|
843
|
+
if buffer_config is None:
|
|
844
|
+
buffer_config = StreamingBufferConfig()
|
|
845
|
+
|
|
846
|
+
failed_attachments = []
|
|
847
|
+
|
|
804
848
|
for attachment_info in all_attachments:
|
|
805
|
-
|
|
806
|
-
|
|
849
|
+
try:
|
|
850
|
+
result = self._process_attachment_safely(attachment_info)
|
|
851
|
+
yield result
|
|
852
|
+
except StorageUploadError as e:
|
|
853
|
+
# Log the failure
|
|
854
|
+
failed_attachments.append(
|
|
855
|
+
{
|
|
856
|
+
"attachment": attachment_info.attachment.file_name,
|
|
857
|
+
"storage_key": attachment_info.attachment.storage_key,
|
|
858
|
+
"error": str(e),
|
|
859
|
+
}
|
|
860
|
+
)
|
|
861
|
+
logger.error(
|
|
862
|
+
f"Failed to process attachment {attachment_info.attachment.file_name} "
|
|
863
|
+
f"({attachment_info.attachment.storage_key}): {e}"
|
|
864
|
+
)
|
|
865
|
+
|
|
866
|
+
# If fail_fast is enabled, re-raise the exception
|
|
867
|
+
if buffer_config.fail_fast_on_attachment_errors:
|
|
868
|
+
raise
|
|
869
|
+
|
|
870
|
+
# Create a placeholder file with error information if error details are enabled
|
|
871
|
+
if buffer_config.include_error_details:
|
|
872
|
+
error_content = (
|
|
873
|
+
f"Error: Failed to retrieve attachment - {e}".encode("utf-8")
|
|
874
|
+
)
|
|
875
|
+
error_filename = (
|
|
876
|
+
f"ERROR_{attachment_info.attachment.file_name or 'unknown'}"
|
|
877
|
+
)
|
|
878
|
+
yield (
|
|
879
|
+
f"errors/{error_filename}",
|
|
880
|
+
datetime.now(),
|
|
881
|
+
DEFAULT_FILE_MODE,
|
|
882
|
+
_ZIP_32_TYPE(),
|
|
883
|
+
iter([error_content]),
|
|
884
|
+
)
|
|
885
|
+
|
|
886
|
+
# Log summary of failed attachments
|
|
887
|
+
if failed_attachments:
|
|
888
|
+
logger.warning(
|
|
889
|
+
f"Failed to process {len(failed_attachments)} attachments: "
|
|
890
|
+
f"{[att['attachment'] for att in failed_attachments]}"
|
|
891
|
+
)
|
|
892
|
+
|
|
893
|
+
# Create a summary error file with details about all failures if error details are enabled
|
|
894
|
+
if buffer_config.include_error_details:
|
|
895
|
+
yield from self._handle_attachment_error(
|
|
896
|
+
all_attachments, failed_attachments
|
|
897
|
+
)
|
|
807
898
|
|
|
808
899
|
def _transform_data_for_access_package(
|
|
809
900
|
self, data: dict[str, Any], all_attachments: list[AttachmentProcessingInfo]
|