ethyca-fides 2.68.1b2__py2.py3-none-any.whl → 2.68.1b4__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ethyca-fides might be problematic. Click here for more details.
- {ethyca_fides-2.68.1b2.dist-info → ethyca_fides-2.68.1b4.dist-info}/METADATA +3 -1
- {ethyca_fides-2.68.1b2.dist-info → ethyca_fides-2.68.1b4.dist-info}/RECORD +253 -232
- fides/_version.py +3 -3
- fides/api/alembic/migrations/versions/90502bcda282_update_request_tasks_add_polling_async.py +35 -0
- fides/api/alembic/migrations/versions/b1a2c3d4e5f6_add_location_to_privacy_request.py +26 -0
- fides/api/api/v1/api.py +2 -0
- fides/api/api/v1/endpoints/dsr_package_link.py +167 -0
- fides/api/api/v1/endpoints/privacy_request_endpoints.py +31 -1
- fides/api/api/v1/endpoints/user_endpoints.py +4 -0
- fides/api/common_exceptions.py +12 -3
- fides/api/models/detection_discovery/core.py +6 -0
- fides/api/models/privacy_request/privacy_request.py +1 -0
- fides/api/models/privacy_request/request_task.py +25 -0
- fides/api/models/privacy_request/webhook.py +33 -1
- fides/api/oauth/utils.py +122 -57
- fides/api/schemas/application_config.py +7 -0
- fides/api/schemas/connection_configuration/connection_type_system_map.py +6 -0
- fides/api/schemas/enums/__init__.py +0 -0
- fides/api/schemas/enums/connection_category.py +20 -0
- fides/api/schemas/enums/integration_feature.py +23 -0
- fides/api/schemas/external_https.py +9 -0
- fides/api/schemas/privacy_center_config.py +48 -19
- fides/api/schemas/privacy_request.py +16 -0
- fides/api/schemas/saas/display_info.py +19 -0
- fides/api/schemas/saas/saas_config.py +2 -0
- fides/api/schemas/storage/storage.py +4 -0
- fides/api/service/async_dsr/__init__.py +0 -0
- fides/api/service/async_dsr/async_dsr_service.py +75 -0
- fides/api/service/connectors/saas_connector.py +5 -6
- fides/api/service/privacy_request/dsr_package/dsr_report_builder.py +6 -4
- fides/api/service/privacy_request/request_runner_service.py +41 -4
- fides/api/service/privacy_request/request_service.py +50 -2
- fides/api/service/storage/storage_uploader_service.py +80 -5
- fides/api/service/storage/streaming/__init__.py +42 -0
- fides/api/service/storage/streaming/base_storage_client.py +61 -0
- fides/api/service/storage/streaming/dsr_storage.py +98 -0
- fides/api/service/storage/streaming/retry.py +282 -0
- fides/api/service/storage/streaming/s3/__init__.py +5 -0
- fides/api/service/storage/streaming/s3/s3_storage_client.py +113 -0
- fides/api/service/storage/streaming/s3/streaming_s3.py +196 -0
- fides/api/service/storage/streaming/schemas.py +173 -0
- fides/api/service/storage/streaming/smart_open_client.py +265 -0
- fides/api/service/storage/streaming/smart_open_streaming_storage.py +998 -0
- fides/api/service/storage/streaming/storage_client_factory.py +60 -0
- fides/api/task/graph_task.py +4 -4
- fides/api/task/manual/manual_task_graph_task.py +3 -4
- fides/api/util/connection_type.py +20 -0
- fides/api/util/text.py +51 -0
- fides/common/api/v1/urn_registry.py +3 -0
- fides/config/execution_settings.py +4 -0
- fides/service/privacy_request/privacy_request_service.py +84 -9
- fides/ui-build/static/admin/404.html +1 -1
- fides/ui-build/static/admin/_next/static/LRCvfOqg1kP5kGnkD84G4/_buildManifest.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1099-b973dfdfc5c3de90.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1345-b60d1f3442379c73.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{1817-c90365325f8a3d75.js → 1817-74692de5d760a664.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{1975.e5cc7a1ccd477671.js → 1975.78e719130cfe3fd6.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{2921-46f9465c2852a46b.js → 2921-2d9261e8e2e127c0.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/3620-ebd89f91b82661e8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3729-ccf90cdaae158f39.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3847-2759bf1f47a1d29e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3855-4174a4d4c205d6e8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3872-660aba76572c811b.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{3923-a33633feba5e655e.js → 3923-c6cdc2e5278ae9a7.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{401-741bb31b586b7c96.js → 401-8bc2c6c84172c096.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{4121-94354b50a41f8497.js → 4121-9a4ebceff9accb7f.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/431-86ad2beeb93c95c9.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4608-4d31340b0d0157c1.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4786-aaef673b30c19e2e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4808-a654c7f7a1ca62c8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4844-cd7e1d0c7bb94094.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5258-bc4a25d43e4aa07d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5487-37c78c4799ba5223.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/549-2213dc1c34143cda.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{6084-02abe12327fc3dbc.js → 6084-55cc66e7c94f0686.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{6853-270261ef5537a106.js → 6853-313ce974d33432fb.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/6954-021bd06d0ab59c3c.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7476-2fc286c2a9125eb8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7630-b9a41262a69edf5e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/768-034e121688a3bbdd.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{787-5ba991cad1f7664a.js → 787-8df7118742e84908.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/79-d2ace89108ead8ae.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/796-2de6dac5f311d54a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/8002-cfdc6574bd841892.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/9046-c44e41da49338c6c.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/9676.b7d5d1d90b9da224.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{9826-8c81c97a72510fcf.js → 9826-d9addbd5ac990fa4.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/9951-6ee5c0a23951a07f.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{404-9174cdb70126c2c5.js → 404-9644eb282f2dcd71.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{_app-2c10f6b217b7978b.js → _app-284cba7174fa1f16.js} +136 -135
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{manual-621416493c89ef01.js → manual-42b7fd34712f49bd.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{multiple-0b9908c3e1dfe49e.js → multiple-4f164eab0960bbe0.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-985d3c9179e69d7f.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-5bb1b31ae8752250.js → add-vendors-61090926e5f98a5d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-17ffe691b91cee2e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-4e4d9426743b5cb4.js → [id]-95c13bca5c1e575e.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-experience-d72460348fadcab8.js → privacy-experience-609399510a60beb9.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-3e7ddc252da00c98.js → [id]-d7d8f228ac74b26e.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-35a7c305beee9428.js → new-821c0f82d5a2b7d4.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-8365782543cf6ab9.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/{properties-ab96939421639153.js → properties-40a7aa65f4d13cf9.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-e4bacfc5c2ed2324.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{consent-13240e3ca77acfeb.js → consent-70c5c6aa5389d99f.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/{[resourceUrn]-aad6047a4604b945.js → [resourceUrn]-adc500a03e239857.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/{[projectUrn]-bd37b407c80c6986.js → [projectUrn]-3207f62e5012611b.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-7b42dee0fb696658.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/{[resourceUrn]-b6b98cea25dd94fa.js → [resourceUrn]-c8b3d090e4ba60d3.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-31a45ea2ca2a7f04.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-6172c2eb539319fd.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-945d354ff057fb03.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-d9795e00f39cf4e9.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-657833fd8528280f.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-31e6c54794a9883e.js → [resourceUrn]-22eec362dfbb1d2a.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-2822a423a7ad0550.js → detection-4decce5ef996e563.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-f98dd251babb7e28.js → [resourceUrn]-01acdd1ad492fd89.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-56eb4c014f0d96a3.js → discovery-85fdbf4cde60d910.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{datamap-8f88dc31c5144ea8.js → datamap-3a4b89fb21d14753.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/[...subfieldNames]-cb8d303f56091bd5.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]-401c8be76d9daec7.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-97e2d375b21cfe43.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-40ef544ca1f2c9b9.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset-e3c763f8e71f8e24.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{[id]-67a7fe58b96ea739.js → [id]-152e5d15705ec072.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-651b10cae0e99a05.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-03c54bc9fb18d2b0.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{index-876bfd7210040cec.js → index-3d19b9ffa15a928a.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-4b0bb4ccfb237d41.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations-78d4e0c14654148b.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{[id]-6e796c3fe632280b.js → [id]-72cb360a6d14e701.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{add-template-fa0f3841c5bdfdeb.js → add-template-0ed67cf774d5cbf5.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/messaging-b06a2204e2a5b667.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-7050899b3f792129.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{AntForm-11503454a62d8d7b.js → AntForm-7c3466f4d5797e55.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikAntFormItem-a504941807bdb7f1.js → FormikAntFormItem-8de252f25871bab9.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikControlled-0119403c8ff97f83.js → FormikControlled-cd6de0da47f980cf.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikField-94f6d57d6c94ddf7.js → FormikField-7c238a881fe30e28.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/{forms-ed1a3ae09d72df89.js → forms-d4f3e8f67f76f146.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/table-migration-c9220e20c1d93758.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-b9d6886a3f157120.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-9c1fd7867b2d80d7.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-fc959ed21dbce38c.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure-44a4a638dcb2722a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-1433c9f9501a884f.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-41976b28503623cd.js → [id]-16e0b42cb342aa5f.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-cb438d8f5ec6007a.js → add-property-ebd114a86b809391.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{properties-b6db7036993709b3.js → properties-901be5fa4a48f48c.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-da9ced1e20681154.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/alpha-0174554c0ac5958f.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/about-6f45ddbf675e66d2.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-275c49e6089c5c9f.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-1a8d05e19f06d857.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-49d86b9ca4523ca6.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-386368bf7cb31771.js → domain-records-f71b4b95d91db926.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-a595cad18cf04673.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/email-templates-6f7f9751689b042c.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-b41fb5ad277088ab.js → locations-e2c88d7f779fe604.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-c65acd2b7ab04753.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-a94dfeea43fbca7d.js → regulations-c1c699eeb40a9dc0.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-a274e2191b87e315.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-18b316e2dad73731.js → [id]-4a48b4f996a64957.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems-30debc87925634d9.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-ca625b1296a029f0.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/{[id]-3237881945acc0ee.js → [id]-7a3180b235eb8846.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{user-management-a3a50d9d79066935.js → user-management-5e2d0acf575252ca.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{webpack-69658aeaf6155d89.js → webpack-4502d4d67006b48f.js} +1 -1
- fides/ui-build/static/admin/_next/static/css/43d0c0fc207767eb.css +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/[monitorId]/[systemId].html +1 -1
- fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +1 -1
- 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-preview.js +1 -1
- fides/ui-build/static/admin/lib/fides-tcf.js +2 -2
- fides/ui-build/static/admin/login/[provider].html +1 -1
- fides/ui-build/static/admin/login.html +1 -1
- fides/ui-build/static/admin/messaging/[id].html +1 -1
- fides/ui-build/static/admin/messaging/add-template.html +1 -1
- fides/ui-build/static/admin/messaging.html +1 -1
- 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/poc/table-migration.html +1 -1
- fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
- fides/ui-build/static/admin/privacy-requests/configure/messaging.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/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.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/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/ui-build/static/admin/_next/static/chunks/203-0c6cadcda98bdd33.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3450-9314e1b15df8a8da.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3855-4267fd8193e7f525.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3872-ac5feefd40b61ae3.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/409-5bc4369b80a8c11d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4230-1ebc8c0ab293a077.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/431-a34d7ceff17c2169.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4608-557fb24665b2e4bf.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5309-ffdec884eec79d29.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5574-831167a8da90e2e6.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6662-499c189f932a35aa.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6780-7d28e030f6516e5d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6882-7cc1d14e27a80c10.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6954-7784e8d5ad6b8110.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/7476-4de465016d3433b4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/7630-2a5c57787632693d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/7725-c79513b04113112b.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/79-98cfab20bb831137.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/796-0b768155bf20505f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/8735-f84afcc50885883c.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9046-97a972cc8a8ed24d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9226-318dadf1c050ecda.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9676.9e6828b42ef05e06.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9951-4df2b67e0def5500.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-18e96ce81dab51a4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-54d7c7310763c66d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-6bc3b73a21576869.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-fe3d6887fecf0f86.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-e4770acf7044e2f5.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-0db635c3483c9da8.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-0c0e0a7798345541.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-3c56e5fe072a44c6.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-58827eb86516931f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-6a90131dcecd694c.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/[...subfieldNames]-145fe9e4cfcb231d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]-8a1e5d140785c1e9.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-227b5db4b472a6a7.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-8401f17fe5d9a1dc.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset-7d77b3ad069be268.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-90a8df230cb89877.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-cfb25b02abb8da71.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-4e286a1e501a0c73.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations-3fdc55d4c129e618.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/messaging-8f9c006b6166f002.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-6ba7ae4f26c06cb0.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/table-migration-e8db3ad525e7ddbd.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-c14dd24592369467.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-100d7d03930629a8.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-6f8d1b3ec83cfcf0.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure-3ce15577435d47cb.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-709bcb0bc6a5382d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-4bc3e281409265cc.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/alpha-1ea40fcd6b4268bf.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/about-65c7600fadc6e55a.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-33dab986141b3663.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-1195042727c399ed.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-71b98858ecb4e097.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-cf427e04f862b5d2.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/email-templates-eabeeec5bf2773c6.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-ee56698ae3a6a78b.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-0e2e98cc38ee5499.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems-c32589c86081b750.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-a8f09bf8f3204ca7.js +0 -1
- fides/ui-build/static/admin/_next/static/css/a72179b1754aadd3.css +0 -1
- fides/ui-build/static/admin/_next/static/qvk5eMANVfwYkdURE7fgG/_buildManifest.js +0 -1
- {ethyca_fides-2.68.1b2.dist-info → ethyca_fides-2.68.1b4.dist-info}/WHEEL +0 -0
- {ethyca_fides-2.68.1b2.dist-info → ethyca_fides-2.68.1b4.dist-info}/entry_points.txt +0 -0
- {ethyca_fides-2.68.1b2.dist-info → ethyca_fides-2.68.1b4.dist-info}/licenses/LICENSE +0 -0
- {ethyca_fides-2.68.1b2.dist-info → ethyca_fides-2.68.1b4.dist-info}/top_level.txt +0 -0
- /fides/ui-build/static/admin/_next/static/{qvk5eMANVfwYkdURE7fgG → LRCvfOqg1kP5kGnkD84G4}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
from typing import Annotated, Any, Optional
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field, field_validator
|
|
4
|
+
|
|
5
|
+
# multipart upload requirements
|
|
6
|
+
MIN_PART_SIZE = 5 * 1024 * 1024 # 5MB minimum part size for AWS S3 uploads
|
|
7
|
+
ZIP_BUFFER_THRESHOLD = 5 * 1024 * 1024 # 5MB threshold for zip buffer uploads
|
|
8
|
+
CHUNK_SIZE_THRESHOLD = 5 * 1024 * 1024 # 5MB threshold for chunk-based uploads
|
|
9
|
+
LARGE_FILE_THRESHOLD = 25 * 1024 * 1024 # 25MB threshold for large file handling
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AttachmentInfo(BaseModel):
|
|
13
|
+
"""Schema for attachment information in streaming storage"""
|
|
14
|
+
|
|
15
|
+
storage_key: str = Field(
|
|
16
|
+
..., description="Storage key for the attachment (cloud-agnostic)"
|
|
17
|
+
)
|
|
18
|
+
file_name: Optional[str] = Field(None, description="Human-readable filename")
|
|
19
|
+
size: Optional[int] = Field(None, ge=0, description="File size in bytes")
|
|
20
|
+
content_type: Optional[str] = Field(None, description="MIME type of the file")
|
|
21
|
+
|
|
22
|
+
@field_validator("storage_key")
|
|
23
|
+
@classmethod
|
|
24
|
+
def validate_storage_key(cls, v: str) -> str:
|
|
25
|
+
if not v or not v.strip():
|
|
26
|
+
raise ValueError("storage_key cannot be empty or whitespace")
|
|
27
|
+
return v.strip()
|
|
28
|
+
|
|
29
|
+
@field_validator("file_name")
|
|
30
|
+
@classmethod
|
|
31
|
+
def validate_file_name(cls, v: Optional[str]) -> Optional[str]:
|
|
32
|
+
if v is not None and (not v or not v.strip()):
|
|
33
|
+
raise ValueError("file_name cannot be empty or whitespace if provided")
|
|
34
|
+
return v.strip() if v else None
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class StorageUploadConfig(BaseModel):
|
|
38
|
+
"""Configuration for storage upload operations"""
|
|
39
|
+
|
|
40
|
+
bucket_name: str = Field(..., description="Storage bucket name")
|
|
41
|
+
file_key: str = Field(..., description="File key in storage")
|
|
42
|
+
max_workers: int = Field(
|
|
43
|
+
default=5, ge=1, le=20, description="Maximum parallel workers"
|
|
44
|
+
)
|
|
45
|
+
resp_format: str = Field(..., description="Response format (csv, json, html)")
|
|
46
|
+
|
|
47
|
+
@field_validator("bucket_name", "file_key")
|
|
48
|
+
@classmethod
|
|
49
|
+
def validate_storage_identifiers(cls, v: str) -> str:
|
|
50
|
+
if not v or not v.strip():
|
|
51
|
+
raise ValueError("Storage identifier cannot be empty or whitespace")
|
|
52
|
+
return v.strip()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class PackageSplitConfig(BaseModel):
|
|
56
|
+
"""Configuration for package splitting operations"""
|
|
57
|
+
|
|
58
|
+
max_attachments: int = Field(
|
|
59
|
+
default=100, ge=1, le=1000, description="Max attachments per package"
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
@field_validator("max_attachments")
|
|
63
|
+
@classmethod
|
|
64
|
+
def validate_max_attachments(cls, v: int) -> int:
|
|
65
|
+
if v < 1:
|
|
66
|
+
raise ValueError("max_attachments must be at least 1")
|
|
67
|
+
return v
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class StreamingBufferConfig(BaseModel):
|
|
71
|
+
"""Configuration for streaming buffer operations"""
|
|
72
|
+
|
|
73
|
+
zip_buffer_threshold: int = Field(
|
|
74
|
+
default=5 * 1024 * 1024,
|
|
75
|
+
ge=1024 * 1024,
|
|
76
|
+
description="Zip buffer threshold in bytes (default: 5MB)",
|
|
77
|
+
)
|
|
78
|
+
stream_buffer_threshold: int = Field(
|
|
79
|
+
default=1024 * 1024,
|
|
80
|
+
ge=1024 * 1024,
|
|
81
|
+
description="Stream buffer threshold in bytes (default: 1MB)",
|
|
82
|
+
)
|
|
83
|
+
chunk_size_threshold: int = Field(
|
|
84
|
+
default=1024 * 1024,
|
|
85
|
+
ge=1024 * 1024,
|
|
86
|
+
description="Chunk size threshold in bytes (default: 1MB)",
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class AttachmentProcessingInfo(BaseModel):
|
|
91
|
+
"""Information for processing a single attachment"""
|
|
92
|
+
|
|
93
|
+
attachment: AttachmentInfo = Field(..., description="Attachment to process")
|
|
94
|
+
base_path: str = Field(..., description="Base path for the attachment in the zip")
|
|
95
|
+
item: dict[str, Any] = Field(..., description="Associated item data")
|
|
96
|
+
|
|
97
|
+
@field_validator("base_path")
|
|
98
|
+
@classmethod
|
|
99
|
+
def validate_base_path(cls, v: str) -> str:
|
|
100
|
+
if not v or not v.strip():
|
|
101
|
+
raise ValueError("base_path cannot be empty or whitespace")
|
|
102
|
+
return v.strip()
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class MultipartUploadResponse(BaseModel):
|
|
106
|
+
"""Response from initiating a multipart upload"""
|
|
107
|
+
|
|
108
|
+
upload_id: Annotated[
|
|
109
|
+
str, Field(..., description="Unique identifier for the multipart upload")
|
|
110
|
+
]
|
|
111
|
+
metadata: Optional[dict[str, Any]] = Field(
|
|
112
|
+
default=None, description="Additional metadata from the storage provider"
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
model_config = {
|
|
116
|
+
"extra": "allow", # Allow extra fields from storage providers
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
@field_validator("upload_id")
|
|
120
|
+
@classmethod
|
|
121
|
+
def validate_upload_id(cls, v: Any) -> str:
|
|
122
|
+
"""Validate upload ID is not empty or whitespace."""
|
|
123
|
+
if not isinstance(v, str):
|
|
124
|
+
raise ValueError("Upload ID must be a string")
|
|
125
|
+
if not v or not v.strip():
|
|
126
|
+
raise ValueError("Upload ID cannot be empty or whitespace")
|
|
127
|
+
return v.strip()
|
|
128
|
+
|
|
129
|
+
def is_valid_upload_id(self) -> bool:
|
|
130
|
+
"""Check if the upload ID is valid (not empty or whitespace)"""
|
|
131
|
+
return bool(self.upload_id and self.upload_id.strip())
|
|
132
|
+
|
|
133
|
+
def get_provider_metadata(self, key: str, default: Any = None) -> Any:
|
|
134
|
+
"""Get metadata value by key with fallback to default"""
|
|
135
|
+
if self.metadata is not None:
|
|
136
|
+
return self.metadata.get(key, default) # pylint: disable=no-member
|
|
137
|
+
return default
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class UploadPartResponse(BaseModel):
|
|
141
|
+
"""Response from uploading a part"""
|
|
142
|
+
|
|
143
|
+
etag: Annotated[str, Field(..., description="ETag/checksum of the uploaded part")]
|
|
144
|
+
part_number: Annotated[
|
|
145
|
+
int, Field(..., description="Sequential number of the part (1-10,000)")
|
|
146
|
+
]
|
|
147
|
+
metadata: Optional[dict[str, Any]] = Field(
|
|
148
|
+
default=None, description="Additional metadata from the storage provider"
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
model_config = {
|
|
152
|
+
"extra": "allow", # Allow extra fields from storage providers
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
@field_validator("part_number")
|
|
156
|
+
@classmethod
|
|
157
|
+
def validate_part_number(cls, v: Any) -> int:
|
|
158
|
+
"""Validate part number is within AWS S3 limits (1-10,000)."""
|
|
159
|
+
if not isinstance(v, int):
|
|
160
|
+
raise ValueError("Part number must be an integer")
|
|
161
|
+
if v < 1 or v > 10000:
|
|
162
|
+
raise ValueError("Part number must be between 1 and 10,000")
|
|
163
|
+
return v
|
|
164
|
+
|
|
165
|
+
def is_valid_etag(self) -> bool:
|
|
166
|
+
"""Check if the ETag is valid (not empty and properly formatted)"""
|
|
167
|
+
return bool(self.etag and self.etag.strip())
|
|
168
|
+
|
|
169
|
+
def get_provider_metadata(self, key: str, default: Any = None) -> Any:
|
|
170
|
+
"""Get metadata value by key with fallback to default"""
|
|
171
|
+
if self.metadata is not None:
|
|
172
|
+
return self.metadata.get(key, default) # pylint: disable=no-member
|
|
173
|
+
return default
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
"""Smart-open based storage client for cloud storage operations."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any, Optional
|
|
6
|
+
|
|
7
|
+
import smart_open
|
|
8
|
+
from fideslang.validation import AnyHttpUrlString
|
|
9
|
+
from loguru import logger
|
|
10
|
+
|
|
11
|
+
from fides.api.service.storage.streaming.retry import retry_cloud_storage_operation
|
|
12
|
+
from fides.api.service.storage.streaming.schemas import (
|
|
13
|
+
MIN_PART_SIZE,
|
|
14
|
+
MultipartUploadResponse,
|
|
15
|
+
UploadPartResponse,
|
|
16
|
+
)
|
|
17
|
+
from fides.api.service.storage.streaming.storage_client_factory import (
|
|
18
|
+
StorageClientFactory,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class SmartOpenStorageClient:
|
|
23
|
+
"""Smart-open based storage client that supports multiple cloud providers.
|
|
24
|
+
|
|
25
|
+
This client uses smart-open for efficient streaming I/O operations while maintaining
|
|
26
|
+
compatibility with our existing storage interface. It delegates provider-specific
|
|
27
|
+
logic to specialized client implementations.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
min_part_size: int = MIN_PART_SIZE
|
|
31
|
+
|
|
32
|
+
def __init__(self, storage_type: str, storage_secrets: Any):
|
|
33
|
+
"""Initialize the smart-open storage client.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
storage_type: Type of storage ('s3', 'gcs', 'azure')
|
|
37
|
+
storage_secrets: Storage credentials and configuration.
|
|
38
|
+
Will be passed to the specific storage client implementation.
|
|
39
|
+
"""
|
|
40
|
+
self.storage_type = StorageClientFactory._normalize_storage_type(storage_type)
|
|
41
|
+
self.storage_secrets = storage_secrets
|
|
42
|
+
self._provider_client = StorageClientFactory.create_client(
|
|
43
|
+
storage_type, storage_secrets
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
def _build_uri(self, bucket: str, key: str) -> str:
|
|
47
|
+
"""Build the URI for the storage location.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
bucket: Storage bucket/container name
|
|
51
|
+
key: Object key/path
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
URI string for smart-open
|
|
55
|
+
"""
|
|
56
|
+
return self._provider_client.build_uri(bucket, key)
|
|
57
|
+
|
|
58
|
+
def _get_transport_params(self) -> dict[str, Any]:
|
|
59
|
+
"""Get transport parameters for smart-open based on storage type and secrets.
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
Dictionary of transport parameters for smart-open
|
|
63
|
+
"""
|
|
64
|
+
return self._provider_client.get_transport_params()
|
|
65
|
+
|
|
66
|
+
@retry_cloud_storage_operation(
|
|
67
|
+
provider="smart_open_storage",
|
|
68
|
+
operation_name="put_object",
|
|
69
|
+
max_retries=3,
|
|
70
|
+
base_delay=2.0,
|
|
71
|
+
max_delay=30.0,
|
|
72
|
+
)
|
|
73
|
+
def put_object(
|
|
74
|
+
self,
|
|
75
|
+
bucket: str,
|
|
76
|
+
key: str,
|
|
77
|
+
body: Any,
|
|
78
|
+
content_type: Optional[str] = None,
|
|
79
|
+
) -> dict[str, Any]:
|
|
80
|
+
"""Upload an object to storage using smart-open.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
bucket: Storage bucket/container name
|
|
84
|
+
key: Object key/path
|
|
85
|
+
body: Object content (file-like object, bytes, or string)
|
|
86
|
+
content_type: MIME type of the object
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
Response dictionary with upload result
|
|
90
|
+
"""
|
|
91
|
+
uri = self._build_uri(bucket, key)
|
|
92
|
+
transport_params = self._get_transport_params()
|
|
93
|
+
|
|
94
|
+
# Handle content type and metadata
|
|
95
|
+
if content_type:
|
|
96
|
+
transport_params["content_type"] = content_type
|
|
97
|
+
|
|
98
|
+
try:
|
|
99
|
+
with smart_open.open(uri, "wb", transport_params=transport_params) as fout:
|
|
100
|
+
if hasattr(body, "read"):
|
|
101
|
+
# File-like object
|
|
102
|
+
fout.write(body.read())
|
|
103
|
+
elif isinstance(body, (bytes, bytearray)):
|
|
104
|
+
# Bytes
|
|
105
|
+
fout.write(body)
|
|
106
|
+
elif isinstance(body, str):
|
|
107
|
+
# String
|
|
108
|
+
fout.write(body.encode("utf-8"))
|
|
109
|
+
else:
|
|
110
|
+
# Try to convert to string
|
|
111
|
+
fout.write(str(body).encode("utf-8"))
|
|
112
|
+
|
|
113
|
+
logger.debug(f"Successfully uploaded object to {uri}")
|
|
114
|
+
return {"status": "success", "uri": uri}
|
|
115
|
+
|
|
116
|
+
except Exception as e:
|
|
117
|
+
logger.error(f"Failed to upload object to {uri}: {e}")
|
|
118
|
+
raise
|
|
119
|
+
|
|
120
|
+
@retry_cloud_storage_operation(
|
|
121
|
+
provider="smart_open_storage",
|
|
122
|
+
operation_name="get_object",
|
|
123
|
+
max_retries=3,
|
|
124
|
+
base_delay=2.0,
|
|
125
|
+
max_delay=30.0,
|
|
126
|
+
)
|
|
127
|
+
def get_object(self, bucket: str, key: str) -> bytes:
|
|
128
|
+
"""Get the full content of an object using smart-open.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
bucket: Storage bucket/container name
|
|
132
|
+
key: Object key/path
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
Object content as bytes
|
|
136
|
+
"""
|
|
137
|
+
uri = self._build_uri(bucket, key)
|
|
138
|
+
transport_params = self._get_transport_params()
|
|
139
|
+
|
|
140
|
+
try:
|
|
141
|
+
with smart_open.open(uri, "rb", transport_params=transport_params) as fin:
|
|
142
|
+
return fin.read()
|
|
143
|
+
|
|
144
|
+
except Exception as e:
|
|
145
|
+
logger.error(f"Failed to read object from {uri}: {e}")
|
|
146
|
+
raise
|
|
147
|
+
|
|
148
|
+
def generate_presigned_url(
|
|
149
|
+
self, bucket: str, key: str, ttl_seconds: Optional[int] = None
|
|
150
|
+
) -> AnyHttpUrlString:
|
|
151
|
+
"""Generate a presigned URL for the object.
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
bucket: Storage bucket/container name
|
|
155
|
+
key: Object key/path
|
|
156
|
+
ttl_seconds: Time to live in seconds
|
|
157
|
+
|
|
158
|
+
Returns:
|
|
159
|
+
Presigned URL for the object
|
|
160
|
+
|
|
161
|
+
Raises:
|
|
162
|
+
Exception: If presigned URL generation fails
|
|
163
|
+
"""
|
|
164
|
+
return self._provider_client.generate_presigned_url(bucket, key, ttl_seconds)
|
|
165
|
+
|
|
166
|
+
# Multipart upload methods - these are simplified since smart-open handles streaming
|
|
167
|
+
def create_multipart_upload(
|
|
168
|
+
self,
|
|
169
|
+
bucket: str,
|
|
170
|
+
key: str,
|
|
171
|
+
content_type: str,
|
|
172
|
+
metadata: Optional[dict[str, str]] = None,
|
|
173
|
+
) -> MultipartUploadResponse:
|
|
174
|
+
"""Create a multipart upload (simplified for smart-open).
|
|
175
|
+
|
|
176
|
+
Since smart-open handles streaming efficiently, we don't need complex multipart logic.
|
|
177
|
+
This method exists for compatibility but delegates to put_object.
|
|
178
|
+
"""
|
|
179
|
+
# Return a dummy response for compatibility
|
|
180
|
+
return MultipartUploadResponse(
|
|
181
|
+
upload_id="smart_open_streaming",
|
|
182
|
+
metadata={"storage_type": self.storage_type, "method": "streaming"},
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
def upload_part(
|
|
186
|
+
self,
|
|
187
|
+
bucket: str,
|
|
188
|
+
key: str,
|
|
189
|
+
upload_id: str,
|
|
190
|
+
part_number: int,
|
|
191
|
+
body: bytes,
|
|
192
|
+
) -> UploadPartResponse:
|
|
193
|
+
"""Upload a part (simplified for smart-open).
|
|
194
|
+
|
|
195
|
+
Since smart-open handles streaming efficiently, we don't need complex multipart logic.
|
|
196
|
+
This method exists for compatibility but delegates to put_object.
|
|
197
|
+
"""
|
|
198
|
+
# For smart-open, we just upload the part directly
|
|
199
|
+
part_key = f"{key}.part{part_number}"
|
|
200
|
+
self.put_object(bucket, part_key, body)
|
|
201
|
+
|
|
202
|
+
return UploadPartResponse(
|
|
203
|
+
part_number=part_number,
|
|
204
|
+
etag=f"smart_open_part_{part_number}",
|
|
205
|
+
metadata={"storage_type": self.storage_type, "method": "streaming"},
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
@retry_cloud_storage_operation(
|
|
209
|
+
provider="smart_open_storage",
|
|
210
|
+
operation_name="stream_upload",
|
|
211
|
+
max_retries=3,
|
|
212
|
+
base_delay=2.0,
|
|
213
|
+
max_delay=30.0,
|
|
214
|
+
)
|
|
215
|
+
def stream_upload(
|
|
216
|
+
self,
|
|
217
|
+
bucket: str,
|
|
218
|
+
key: str,
|
|
219
|
+
content_type: Optional[str] = None,
|
|
220
|
+
) -> Any:
|
|
221
|
+
"""Get a writable stream for uploading data.
|
|
222
|
+
|
|
223
|
+
This is the main advantage of smart-open - true streaming uploads.
|
|
224
|
+
|
|
225
|
+
Args:
|
|
226
|
+
bucket: Storage bucket/container name
|
|
227
|
+
key: Object key/path
|
|
228
|
+
content_type: MIME type of the object
|
|
229
|
+
|
|
230
|
+
Returns:
|
|
231
|
+
Writable file-like object
|
|
232
|
+
"""
|
|
233
|
+
uri = self._build_uri(bucket, key)
|
|
234
|
+
transport_params = self._get_transport_params()
|
|
235
|
+
|
|
236
|
+
if content_type:
|
|
237
|
+
transport_params["content_type"] = content_type
|
|
238
|
+
|
|
239
|
+
return smart_open.open(uri, "wb", transport_params=transport_params)
|
|
240
|
+
|
|
241
|
+
@retry_cloud_storage_operation(
|
|
242
|
+
provider="smart_open_storage",
|
|
243
|
+
operation_name="stream_read",
|
|
244
|
+
max_retries=3,
|
|
245
|
+
base_delay=2.0,
|
|
246
|
+
max_delay=30.0,
|
|
247
|
+
)
|
|
248
|
+
def stream_read(
|
|
249
|
+
self,
|
|
250
|
+
bucket: str,
|
|
251
|
+
key: str,
|
|
252
|
+
) -> Any:
|
|
253
|
+
"""Get a readable stream for streaming data from cloud storage.
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
bucket: Storage bucket/container name
|
|
257
|
+
key: Object key/path
|
|
258
|
+
|
|
259
|
+
Returns:
|
|
260
|
+
Readable file-like object for streaming content
|
|
261
|
+
"""
|
|
262
|
+
uri = self._build_uri(bucket, key)
|
|
263
|
+
transport_params = self._get_transport_params()
|
|
264
|
+
|
|
265
|
+
return smart_open.open(uri, "rb", transport_params=transport_params)
|