ethyca-fides 2.68.1b1__py2.py3-none-any.whl → 2.68.1b3__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ethyca-fides might be problematic. Click here for more details.

Files changed (309) hide show
  1. {ethyca_fides-2.68.1b1.dist-info → ethyca_fides-2.68.1b3.dist-info}/METADATA +3 -1
  2. {ethyca_fides-2.68.1b1.dist-info → ethyca_fides-2.68.1b3.dist-info}/RECORD +247 -224
  3. fides/_version.py +3 -3
  4. fides/api/alembic/migrations/versions/3baf42d251a6_add_generic_taxonomy_models.py +239 -0
  5. fides/api/alembic/migrations/versions/90502bcda282_update_request_tasks_add_polling_async.py +35 -0
  6. fides/api/api/v1/endpoints/generic_overrides.py +64 -167
  7. fides/api/api/v1/endpoints/privacy_request_endpoints.py +1 -1
  8. fides/api/common_exceptions.py +12 -3
  9. fides/api/db/base.py +6 -0
  10. fides/api/models/detection_discovery/core.py +6 -0
  11. fides/api/models/privacy_request/request_task.py +25 -0
  12. fides/api/models/taxonomy.py +275 -0
  13. fides/api/schemas/privacy_center_config.py +48 -19
  14. fides/api/schemas/storage/storage.py +2 -0
  15. fides/api/service/async_dsr/__init__.py +0 -0
  16. fides/api/service/async_dsr/async_dsr_service.py +75 -0
  17. fides/api/service/connectors/saas_connector.py +5 -6
  18. fides/api/service/deps.py +5 -0
  19. fides/api/service/privacy_request/dsr_package/dsr_report_builder.py +6 -4
  20. fides/api/service/privacy_request/request_service.py +56 -3
  21. fides/api/service/storage/storage_uploader_service.py +80 -5
  22. fides/api/service/storage/streaming/__init__.py +42 -0
  23. fides/api/service/storage/streaming/base_storage_client.py +61 -0
  24. fides/api/service/storage/streaming/dsr_storage.py +98 -0
  25. fides/api/service/storage/streaming/retry.py +282 -0
  26. fides/api/service/storage/streaming/s3/__init__.py +5 -0
  27. fides/api/service/storage/streaming/s3/s3_storage_client.py +113 -0
  28. fides/api/service/storage/streaming/s3/streaming_s3.py +196 -0
  29. fides/api/service/storage/streaming/schemas.py +173 -0
  30. fides/api/service/storage/streaming/smart_open_client.py +265 -0
  31. fides/api/service/storage/streaming/smart_open_streaming_storage.py +998 -0
  32. fides/api/service/storage/streaming/storage_client_factory.py +60 -0
  33. fides/api/task/graph_task.py +4 -4
  34. fides/api/task/manual/manual_task_graph_task.py +14 -4
  35. fides/api/util/connection_type.py +68 -33
  36. fides/config/execution_settings.py +4 -0
  37. fides/data/sample_project/docker-compose.yml +3 -3
  38. fides/service/privacy_request/privacy_request_service.py +1 -9
  39. fides/service/taxonomy/__init__.py +0 -0
  40. fides/service/taxonomy/handlers/__init__.py +11 -0
  41. fides/service/taxonomy/handlers/base.py +42 -0
  42. fides/service/taxonomy/handlers/legacy_handler.py +95 -0
  43. fides/service/taxonomy/taxonomy_service.py +261 -0
  44. fides/service/taxonomy/utils.py +160 -0
  45. fides/ui-build/static/admin/404.html +1 -1
  46. fides/ui-build/static/admin/_next/static/_BLI2ArqQzY5XnXbrcxa2/_buildManifest.js +1 -0
  47. fides/ui-build/static/admin/_next/static/chunks/1099-7b2085a3931da9e4.js +1 -0
  48. fides/ui-build/static/admin/_next/static/chunks/1138-0d846ffef62c580f.js +1 -0
  49. fides/ui-build/static/admin/_next/static/chunks/1345-ab756811e19ff4fc.js +1 -0
  50. fides/ui-build/static/admin/_next/static/chunks/{1817-c90365325f8a3d75.js → 1817-fd21f1f5ef0faffa.js} +1 -1
  51. fides/ui-build/static/admin/_next/static/chunks/{1975.e5cc7a1ccd477671.js → 1975.16126463309143e3.js} +1 -1
  52. fides/ui-build/static/admin/_next/static/chunks/{2921-46f9465c2852a46b.js → 2921-0e5cc63a82e31830.js} +1 -1
  53. fides/ui-build/static/admin/_next/static/chunks/3620-6cceae71bae5b531.js +1 -0
  54. fides/ui-build/static/admin/_next/static/chunks/3729-7d2d52400f1f7413.js +1 -0
  55. fides/ui-build/static/admin/_next/static/chunks/3855-64541570e2f838fb.js +1 -0
  56. fides/ui-build/static/admin/_next/static/chunks/3872-7a18d18a5e287e4e.js +1 -0
  57. fides/ui-build/static/admin/_next/static/chunks/{3923-a33633feba5e655e.js → 3923-5c87b3d7f1626678.js} +1 -1
  58. fides/ui-build/static/admin/_next/static/chunks/{401-741bb31b586b7c96.js → 401-3902e3e98790d401.js} +1 -1
  59. fides/ui-build/static/admin/_next/static/chunks/{4121-94354b50a41f8497.js → 4121-64ef70ef906bbdd0.js} +1 -1
  60. fides/ui-build/static/admin/_next/static/chunks/431-86ad2beeb93c95c9.js +1 -0
  61. fides/ui-build/static/admin/_next/static/chunks/4608-70521532195124de.js +1 -0
  62. fides/ui-build/static/admin/_next/static/chunks/4786-53ef1662f2d0d98c.js +1 -0
  63. fides/ui-build/static/admin/_next/static/chunks/4808-8713433c84a62efe.js +1 -0
  64. fides/ui-build/static/admin/_next/static/chunks/4844-351f99b6644b654e.js +1 -0
  65. fides/ui-build/static/admin/_next/static/chunks/5258-c6f96dc740eb5fb1.js +1 -0
  66. fides/ui-build/static/admin/_next/static/chunks/5487-338800277d36b8d7.js +1 -0
  67. fides/ui-build/static/admin/_next/static/chunks/549-e6453a3526023e85.js +1 -0
  68. fides/ui-build/static/admin/_next/static/chunks/602-80d113e801d7407d.js +1 -0
  69. fides/ui-build/static/admin/_next/static/chunks/{6084-02abe12327fc3dbc.js → 6084-da63f20d9416a982.js} +1 -1
  70. fides/ui-build/static/admin/_next/static/chunks/{6853-270261ef5537a106.js → 6853-1d947b75eb07188c.js} +1 -1
  71. fides/ui-build/static/admin/_next/static/chunks/6954-24f9a4f27d67b732.js +1 -0
  72. fides/ui-build/static/admin/_next/static/chunks/7476-a0dd03bfccf60d0c.js +1 -0
  73. fides/ui-build/static/admin/_next/static/chunks/7630-9fbe06cfb98266fe.js +1 -0
  74. fides/ui-build/static/admin/_next/static/chunks/{787-5ba991cad1f7664a.js → 787-3dd31844cf7fec55.js} +1 -1
  75. fides/ui-build/static/admin/_next/static/chunks/79-dcd20e8b09501c17.js +1 -0
  76. fides/ui-build/static/admin/_next/static/chunks/796-8773e04b64ce2260.js +1 -0
  77. fides/ui-build/static/admin/_next/static/chunks/8002-dcd02da6e5649a1c.js +1 -0
  78. fides/ui-build/static/admin/_next/static/chunks/9046-57eab238570b8bf4.js +1 -0
  79. fides/ui-build/static/admin/_next/static/chunks/9676.bf0a8a6ff6dfd2af.js +1 -0
  80. fides/ui-build/static/admin/_next/static/chunks/{9826-8c81c97a72510fcf.js → 9826-756c958aecab59a2.js} +1 -1
  81. fides/ui-build/static/admin/_next/static/chunks/9951-cdf73904a3adb27b.js +1 -0
  82. fides/ui-build/static/admin/_next/static/chunks/pages/{404-9174cdb70126c2c5.js → 404-dd625a559ada46ca.js} +1 -1
  83. fides/ui-build/static/admin/_next/static/chunks/pages/{_app-65723cd4b8fc36ac.js → _app-b6b09b2878b77b21.js} +136 -135
  84. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{manual-621416493c89ef01.js → manual-92cf5e313be1f9e2.js} +1 -1
  85. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{multiple-0b9908c3e1dfe49e.js → multiple-d6c525ee731a2993.js} +1 -1
  86. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-5664a3ea796e5ffb.js +1 -0
  87. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-5bb1b31ae8752250.js → add-vendors-78f13de90111fd80.js} +1 -1
  88. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-0fc678f3d6d2fcec.js +1 -0
  89. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-4e4d9426743b5cb4.js → [id]-126db59dc25ca326.js} +1 -1
  90. fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-experience-d72460348fadcab8.js → privacy-experience-289605267d6cce7e.js} +1 -1
  91. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-3e7ddc252da00c98.js → [id]-e9fd9b28ac9705af.js} +1 -1
  92. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-35a7c305beee9428.js → new-28c003b6043bd16c.js} +1 -1
  93. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-c643eff04525298e.js +1 -0
  94. fides/ui-build/static/admin/_next/static/chunks/pages/consent/{properties-ab96939421639153.js → properties-3ef5d01779a26455.js} +1 -1
  95. fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-baa4a2f8f08ac224.js +1 -0
  96. fides/ui-build/static/admin/_next/static/chunks/pages/{consent-13240e3ca77acfeb.js → consent-8d4be9e7ec7d2a35.js} +1 -1
  97. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/{[resourceUrn]-aad6047a4604b945.js → [resourceUrn]-f27ec4578c674181.js} +1 -1
  98. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/{[projectUrn]-bd37b407c80c6986.js → [projectUrn]-27b6c255bd9e73b6.js} +1 -1
  99. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-0f66dac32040519c.js +1 -0
  100. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/{[resourceUrn]-b6b98cea25dd94fa.js → [resourceUrn]-3b938562df81c4b0.js} +1 -1
  101. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-ebf5e7fa4e2ffb49.js +1 -0
  102. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-b27c660039d951c9.js +1 -0
  103. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-8ce5d24af470888e.js +1 -0
  104. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-8e35e33928abbcdc.js +1 -0
  105. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-21c141279e66237a.js +1 -0
  106. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-31e6c54794a9883e.js → [resourceUrn]-3bc6a207693fd175.js} +1 -1
  107. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-2822a423a7ad0550.js → detection-da16e73df395ad1d.js} +1 -1
  108. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-f98dd251babb7e28.js → [resourceUrn]-04b242632a114405.js} +1 -1
  109. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-56eb4c014f0d96a3.js → discovery-900fe50183a40d72.js} +1 -1
  110. fides/ui-build/static/admin/_next/static/chunks/pages/{datamap-8f88dc31c5144ea8.js → datamap-4f1f7c3a9531a8f4.js} +1 -1
  111. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/[...subfieldNames]-343294dcb10d9532.js +1 -0
  112. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]-1c097a0809fa5b6f.js +1 -0
  113. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-b47fa2498b534719.js +1 -0
  114. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-a31f881cab25704a.js +1 -0
  115. fides/ui-build/static/admin/_next/static/chunks/pages/dataset-858c59c9e67e318d.js +1 -0
  116. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{[id]-67a7fe58b96ea739.js → [id]-16c28d272225afb6.js} +1 -1
  117. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{new-90a8df230cb89877.js → new-68f502d8b0b5792c.js} +1 -1
  118. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-1eb9acb17b133fd1.js +1 -0
  119. fides/ui-build/static/admin/_next/static/chunks/pages/{index-876bfd7210040cec.js → index-fec557d99211f577.js} +1 -1
  120. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/{[id]-766e57bcf38b5b1e.js → [id]-e613543818d6cbd2.js} +1 -1
  121. fides/ui-build/static/admin/_next/static/chunks/pages/integrations-8069f7c33695fd45.js +1 -0
  122. fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{[id]-6e796c3fe632280b.js → [id]-4a08ca7762a19700.js} +1 -1
  123. fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{add-template-fa0f3841c5bdfdeb.js → add-template-343a965dcdb3d11e.js} +1 -1
  124. fides/ui-build/static/admin/_next/static/chunks/pages/messaging-3ade4c54b1c8a11e.js +1 -0
  125. fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-9103bfb854f71410.js +1 -0
  126. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{AntForm-11503454a62d8d7b.js → AntForm-3b97029bd4d3c3ea.js} +1 -1
  127. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikAntFormItem-a504941807bdb7f1.js → FormikAntFormItem-9d9beb8f0d8a278c.js} +1 -1
  128. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikControlled-0119403c8ff97f83.js → FormikControlled-84a4d8fc60f839ed.js} +1 -1
  129. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikField-94f6d57d6c94ddf7.js → FormikField-1fccf542ab2e33bf.js} +1 -1
  130. fides/ui-build/static/admin/_next/static/chunks/pages/poc/{forms-ed1a3ae09d72df89.js → forms-aa75263ae1ba67bb.js} +1 -1
  131. fides/ui-build/static/admin/_next/static/chunks/pages/poc/table-migration-db334a1cbb102255.js +1 -0
  132. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-11c1e4545c8f528c.js +1 -0
  133. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-192a986f61c23268.js +1 -0
  134. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-9216ac993d71387e.js +1 -0
  135. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure-e55ec84d5380401d.js +1 -0
  136. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-48f447b31c786b80.js +1 -0
  137. fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-41976b28503623cd.js → [id]-a74b51b704b80cb2.js} +1 -1
  138. fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-cb438d8f5ec6007a.js → add-property-8d23f0c55ff6510a.js} +1 -1
  139. fides/ui-build/static/admin/_next/static/chunks/pages/{properties-b6db7036993709b3.js → properties-77acceac4f99e7af.js} +1 -1
  140. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/{datamap-4bc3e281409265cc.js → datamap-e60d398e255f4e00.js} +1 -1
  141. fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/alpha-6aad3f563ed03b3f.js +1 -0
  142. fides/ui-build/static/admin/_next/static/chunks/pages/settings/about-c1b8f3606d160bb1.js +1 -0
  143. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-d9f7f78810d58d08.js +1 -0
  144. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-ee2c7dde99b1dafb.js +1 -0
  145. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-a4dad8ca9de2d07b.js +1 -0
  146. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-386368bf7cb31771.js → domain-records-31c270d228e00581.js} +1 -1
  147. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-996b3f250dd3ea1f.js +1 -0
  148. fides/ui-build/static/admin/_next/static/chunks/pages/settings/email-templates-ee94981326ddcbf4.js +1 -0
  149. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-b41fb5ad277088ab.js → locations-0b831c58966782b8.js} +1 -1
  150. fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-94271ba4a224a353.js +1 -0
  151. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-a94dfeea43fbca7d.js → regulations-41b8136e50320fd3.js} +1 -1
  152. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-52b45569cbc82e60.js +1 -0
  153. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-18b316e2dad73731.js → [id]-36d74e93e54aabaf.js} +1 -1
  154. fides/ui-build/static/admin/_next/static/chunks/pages/systems-24dfc8e2279ced2e.js +1 -0
  155. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-d9675cf5e6083b27.js +1 -0
  156. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/{[id]-3237881945acc0ee.js → [id]-866826d7959df487.js} +1 -1
  157. fides/ui-build/static/admin/_next/static/chunks/pages/{user-management-a3a50d9d79066935.js → user-management-e63b61a8f99ccd57.js} +1 -1
  158. fides/ui-build/static/admin/_next/static/chunks/{webpack-69658aeaf6155d89.js → webpack-6d0a487039bcf30c.js} +1 -1
  159. fides/ui-build/static/admin/_next/static/css/92441453b27e9c34.css +1 -0
  160. fides/ui-build/static/admin/add-systems/manual.html +1 -1
  161. fides/ui-build/static/admin/add-systems/multiple.html +1 -1
  162. fides/ui-build/static/admin/add-systems.html +1 -1
  163. fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
  164. fides/ui-build/static/admin/consent/configure.html +1 -1
  165. fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
  166. fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
  167. fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
  168. fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
  169. fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
  170. fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
  171. fides/ui-build/static/admin/consent/properties.html +1 -1
  172. fides/ui-build/static/admin/consent/reporting.html +1 -1
  173. fides/ui-build/static/admin/consent.html +1 -1
  174. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
  175. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
  176. fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
  177. fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
  178. fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
  179. fides/ui-build/static/admin/data-catalog.html +1 -1
  180. fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/[systemId].html +1 -1
  181. fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +1 -1
  182. fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
  183. fides/ui-build/static/admin/data-discovery/activity.html +1 -1
  184. fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
  185. fides/ui-build/static/admin/data-discovery/detection.html +1 -1
  186. fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
  187. fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
  188. fides/ui-build/static/admin/datamap.html +1 -1
  189. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
  190. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
  191. fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
  192. fides/ui-build/static/admin/dataset/new.html +1 -1
  193. fides/ui-build/static/admin/dataset.html +1 -1
  194. fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
  195. fides/ui-build/static/admin/datastore-connection/new.html +1 -1
  196. fides/ui-build/static/admin/datastore-connection.html +1 -1
  197. fides/ui-build/static/admin/index.html +1 -1
  198. fides/ui-build/static/admin/integrations/[id].html +1 -1
  199. fides/ui-build/static/admin/integrations.html +1 -1
  200. fides/ui-build/static/admin/lib/fides-preview.js +1 -1
  201. fides/ui-build/static/admin/lib/fides-tcf.js +2 -2
  202. fides/ui-build/static/admin/lib/fides.js +1 -1
  203. fides/ui-build/static/admin/login/[provider].html +1 -1
  204. fides/ui-build/static/admin/login.html +1 -1
  205. fides/ui-build/static/admin/messaging/[id].html +1 -1
  206. fides/ui-build/static/admin/messaging/add-template.html +1 -1
  207. fides/ui-build/static/admin/messaging.html +1 -1
  208. fides/ui-build/static/admin/poc/ant-components.html +1 -1
  209. fides/ui-build/static/admin/poc/form-experiments/AntForm.html +1 -1
  210. fides/ui-build/static/admin/poc/form-experiments/FormikAntFormItem.html +1 -1
  211. fides/ui-build/static/admin/poc/form-experiments/FormikControlled.html +1 -1
  212. fides/ui-build/static/admin/poc/form-experiments/FormikField.html +1 -1
  213. fides/ui-build/static/admin/poc/form-experiments/FormikSpreadField.html +1 -1
  214. fides/ui-build/static/admin/poc/forms.html +1 -1
  215. fides/ui-build/static/admin/poc/table-migration.html +1 -1
  216. fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
  217. fides/ui-build/static/admin/privacy-requests/configure/messaging.html +1 -1
  218. fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
  219. fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
  220. fides/ui-build/static/admin/privacy-requests.html +1 -1
  221. fides/ui-build/static/admin/properties/[id].html +1 -1
  222. fides/ui-build/static/admin/properties/add-property.html +1 -1
  223. fides/ui-build/static/admin/properties.html +1 -1
  224. fides/ui-build/static/admin/reporting/datamap.html +1 -1
  225. fides/ui-build/static/admin/settings/about/alpha.html +1 -1
  226. fides/ui-build/static/admin/settings/about.html +1 -1
  227. fides/ui-build/static/admin/settings/consent/[configuration_id]/[purpose_id].html +1 -1
  228. fides/ui-build/static/admin/settings/consent.html +1 -1
  229. fides/ui-build/static/admin/settings/custom-fields.html +1 -1
  230. fides/ui-build/static/admin/settings/domain-records.html +1 -1
  231. fides/ui-build/static/admin/settings/domains.html +1 -1
  232. fides/ui-build/static/admin/settings/email-templates.html +1 -1
  233. fides/ui-build/static/admin/settings/locations.html +1 -1
  234. fides/ui-build/static/admin/settings/organization.html +1 -1
  235. fides/ui-build/static/admin/settings/regulations.html +1 -1
  236. fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
  237. fides/ui-build/static/admin/systems/configure/[id].html +1 -1
  238. fides/ui-build/static/admin/systems.html +1 -1
  239. fides/ui-build/static/admin/taxonomy.html +1 -1
  240. fides/ui-build/static/admin/user-management/new.html +1 -1
  241. fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
  242. fides/ui-build/static/admin/user-management.html +1 -1
  243. fides/ui-build/static/admin/_next/static/chunks/203-0c6cadcda98bdd33.js +0 -1
  244. fides/ui-build/static/admin/_next/static/chunks/3450-9314e1b15df8a8da.js +0 -1
  245. fides/ui-build/static/admin/_next/static/chunks/3855-4267fd8193e7f525.js +0 -1
  246. fides/ui-build/static/admin/_next/static/chunks/3872-ac5feefd40b61ae3.js +0 -1
  247. fides/ui-build/static/admin/_next/static/chunks/409-5bc4369b80a8c11d.js +0 -1
  248. fides/ui-build/static/admin/_next/static/chunks/4230-1ebc8c0ab293a077.js +0 -1
  249. fides/ui-build/static/admin/_next/static/chunks/431-a34d7ceff17c2169.js +0 -1
  250. fides/ui-build/static/admin/_next/static/chunks/4608-557fb24665b2e4bf.js +0 -1
  251. fides/ui-build/static/admin/_next/static/chunks/5309-ffdec884eec79d29.js +0 -1
  252. fides/ui-build/static/admin/_next/static/chunks/5574-831167a8da90e2e6.js +0 -1
  253. fides/ui-build/static/admin/_next/static/chunks/6662-499c189f932a35aa.js +0 -1
  254. fides/ui-build/static/admin/_next/static/chunks/6780-7d28e030f6516e5d.js +0 -1
  255. fides/ui-build/static/admin/_next/static/chunks/6882-7cc1d14e27a80c10.js +0 -1
  256. fides/ui-build/static/admin/_next/static/chunks/6954-7784e8d5ad6b8110.js +0 -1
  257. fides/ui-build/static/admin/_next/static/chunks/7476-4de465016d3433b4.js +0 -1
  258. fides/ui-build/static/admin/_next/static/chunks/7630-2a5c57787632693d.js +0 -1
  259. fides/ui-build/static/admin/_next/static/chunks/7725-c79513b04113112b.js +0 -1
  260. fides/ui-build/static/admin/_next/static/chunks/79-98cfab20bb831137.js +0 -1
  261. fides/ui-build/static/admin/_next/static/chunks/796-0b768155bf20505f.js +0 -1
  262. fides/ui-build/static/admin/_next/static/chunks/8735-f84afcc50885883c.js +0 -1
  263. fides/ui-build/static/admin/_next/static/chunks/9046-97a972cc8a8ed24d.js +0 -1
  264. fides/ui-build/static/admin/_next/static/chunks/9226-318dadf1c050ecda.js +0 -1
  265. fides/ui-build/static/admin/_next/static/chunks/9676.9e6828b42ef05e06.js +0 -1
  266. fides/ui-build/static/admin/_next/static/chunks/9951-4df2b67e0def5500.js +0 -1
  267. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-18e96ce81dab51a4.js +0 -1
  268. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-54d7c7310763c66d.js +0 -1
  269. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-6bc3b73a21576869.js +0 -1
  270. fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-fe3d6887fecf0f86.js +0 -1
  271. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-e4770acf7044e2f5.js +0 -1
  272. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-0db635c3483c9da8.js +0 -1
  273. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-0c0e0a7798345541.js +0 -1
  274. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-3c56e5fe072a44c6.js +0 -1
  275. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-53a763e49ce34a74.js +0 -1
  276. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-6a90131dcecd694c.js +0 -1
  277. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/[...subfieldNames]-145fe9e4cfcb231d.js +0 -1
  278. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]-8a1e5d140785c1e9.js +0 -1
  279. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-227b5db4b472a6a7.js +0 -1
  280. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-8401f17fe5d9a1dc.js +0 -1
  281. fides/ui-build/static/admin/_next/static/chunks/pages/dataset-7d77b3ad069be268.js +0 -1
  282. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-cfb25b02abb8da71.js +0 -1
  283. fides/ui-build/static/admin/_next/static/chunks/pages/integrations-3fdc55d4c129e618.js +0 -1
  284. fides/ui-build/static/admin/_next/static/chunks/pages/messaging-8f9c006b6166f002.js +0 -1
  285. fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-6ba7ae4f26c06cb0.js +0 -1
  286. fides/ui-build/static/admin/_next/static/chunks/pages/poc/table-migration-e8db3ad525e7ddbd.js +0 -1
  287. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-c14dd24592369467.js +0 -1
  288. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-100d7d03930629a8.js +0 -1
  289. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-6f8d1b3ec83cfcf0.js +0 -1
  290. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure-3ce15577435d47cb.js +0 -1
  291. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-f43a988542813110.js +0 -1
  292. fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/alpha-1ea40fcd6b4268bf.js +0 -1
  293. fides/ui-build/static/admin/_next/static/chunks/pages/settings/about-65c7600fadc6e55a.js +0 -1
  294. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-33dab986141b3663.js +0 -1
  295. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-1195042727c399ed.js +0 -1
  296. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-71b98858ecb4e097.js +0 -1
  297. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-cf427e04f862b5d2.js +0 -1
  298. fides/ui-build/static/admin/_next/static/chunks/pages/settings/email-templates-eabeeec5bf2773c6.js +0 -1
  299. fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-ee56698ae3a6a78b.js +0 -1
  300. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-0e2e98cc38ee5499.js +0 -1
  301. fides/ui-build/static/admin/_next/static/chunks/pages/systems-c32589c86081b750.js +0 -1
  302. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-a8f09bf8f3204ca7.js +0 -1
  303. fides/ui-build/static/admin/_next/static/css/e1628f15dd5f019b.css +0 -1
  304. fides/ui-build/static/admin/_next/static/tzF4yti8NslASlGnxnZ8m/_buildManifest.js +0 -1
  305. {ethyca_fides-2.68.1b1.dist-info → ethyca_fides-2.68.1b3.dist-info}/WHEEL +0 -0
  306. {ethyca_fides-2.68.1b1.dist-info → ethyca_fides-2.68.1b3.dist-info}/entry_points.txt +0 -0
  307. {ethyca_fides-2.68.1b1.dist-info → ethyca_fides-2.68.1b3.dist-info}/licenses/LICENSE +0 -0
  308. {ethyca_fides-2.68.1b1.dist-info → ethyca_fides-2.68.1b3.dist-info}/top_level.txt +0 -0
  309. /fides/ui-build/static/admin/_next/static/{tzF4yti8NslASlGnxnZ8m → _BLI2ArqQzY5XnXbrcxa2}/_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)