deltacat 1.1.5__tar.gz → 1.1.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. {deltacat-1.1.5 → deltacat-1.1.6}/PKG-INFO +1 -1
  2. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/__init__.py +1 -1
  3. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/aws/constants.py +3 -1
  4. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/aws/s3u.py +71 -24
  5. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/utils/task_options.py +5 -2
  6. deltacat-1.1.6/deltacat/tests/aws/test_s3u.py +124 -0
  7. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat.egg-info/PKG-INFO +1 -1
  8. deltacat-1.1.5/deltacat/tests/aws/test_s3u.py +0 -12
  9. {deltacat-1.1.5 → deltacat-1.1.6}/MANIFEST.in +0 -0
  10. {deltacat-1.1.5 → deltacat-1.1.6}/README.md +0 -0
  11. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/aws/__init__.py +0 -0
  12. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/aws/clients.py +0 -0
  13. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/aws/redshift/__init__.py +0 -0
  14. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/aws/redshift/model/__init__.py +0 -0
  15. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/aws/redshift/model/manifest.py +0 -0
  16. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/benchmarking/__init__.py +0 -0
  17. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/benchmarking/benchmark_parquet_reads.py +0 -0
  18. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/benchmarking/conftest.py +0 -0
  19. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/catalog/__init__.py +0 -0
  20. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/catalog/default_catalog_impl/__init__.py +0 -0
  21. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/catalog/delegate.py +0 -0
  22. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/catalog/interface.py +0 -0
  23. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/catalog/model/__init__.py +0 -0
  24. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/catalog/model/catalog.py +0 -0
  25. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/catalog/model/table_definition.py +0 -0
  26. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/__init__.py +0 -0
  27. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/__init__.py +0 -0
  28. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/compaction_session.py +0 -0
  29. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/model/__init__.py +0 -0
  30. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/model/compact_partition_params.py +0 -0
  31. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/model/compaction_session_audit_info.py +0 -0
  32. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/model/compactor_version.py +0 -0
  33. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/model/dedupe_result.py +0 -0
  34. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/model/delta_annotated.py +0 -0
  35. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/model/delta_file_envelope.py +0 -0
  36. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/model/delta_file_locator.py +0 -0
  37. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/model/hash_bucket_result.py +0 -0
  38. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/model/materialize_result.py +0 -0
  39. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/model/primary_key_index.py +0 -0
  40. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/model/pyarrow_write_result.py +0 -0
  41. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/model/repartition_result.py +0 -0
  42. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/model/round_completion_info.py +0 -0
  43. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/model/table_object_store.py +0 -0
  44. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/repartition_session.py +0 -0
  45. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/steps/__init__.py +0 -0
  46. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/steps/dedupe.py +0 -0
  47. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/steps/hash_bucket.py +0 -0
  48. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/steps/materialize.py +0 -0
  49. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/steps/repartition.py +0 -0
  50. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/utils/__init__.py +0 -0
  51. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/utils/io.py +0 -0
  52. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/utils/primary_key_index.py +0 -0
  53. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/utils/round_completion_file.py +0 -0
  54. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/utils/sort_key.py +0 -0
  55. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor/utils/system_columns.py +0 -0
  56. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/__init__.py +0 -0
  57. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/compaction_session.py +0 -0
  58. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/constants.py +0 -0
  59. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/deletes/__init__.py +0 -0
  60. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/deletes/delete_file_envelope.py +0 -0
  61. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/deletes/delete_strategy.py +0 -0
  62. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/deletes/delete_strategy_equality_delete.py +0 -0
  63. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/deletes/model.py +0 -0
  64. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/deletes/utils.py +0 -0
  65. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/model/__init__.py +0 -0
  66. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/model/hash_bucket_input.py +0 -0
  67. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/model/hash_bucket_result.py +0 -0
  68. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/model/merge_file_group.py +0 -0
  69. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/model/merge_input.py +0 -0
  70. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/model/merge_result.py +0 -0
  71. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/steps/__init__.py +0 -0
  72. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/steps/hash_bucket.py +0 -0
  73. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/steps/merge.py +0 -0
  74. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/utils/__init__.py +0 -0
  75. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/utils/content_type_params.py +0 -0
  76. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/utils/dedupe.py +0 -0
  77. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/utils/delta.py +0 -0
  78. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/utils/io.py +0 -0
  79. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/utils/merge.py +0 -0
  80. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/compactor_v2/utils/primary_key_index.py +0 -0
  81. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/merge_on_read/__init__.py +0 -0
  82. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/merge_on_read/daft.py +0 -0
  83. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/merge_on_read/model/__init__.py +0 -0
  84. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/merge_on_read/model/merge_on_read_params.py +0 -0
  85. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/merge_on_read/utils/__init__.py +0 -0
  86. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/merge_on_read/utils/delta.py +0 -0
  87. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/metastats/__init__.py +0 -0
  88. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/metastats/config/__init__.py +0 -0
  89. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/metastats/meta_stats.py +0 -0
  90. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/metastats/model/__init__.py +0 -0
  91. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/metastats/model/partition_stats_dict.py +0 -0
  92. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/metastats/model/stats_cluster_size_estimator.py +0 -0
  93. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/metastats/stats.py +0 -0
  94. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/metastats/utils/__init__.py +0 -0
  95. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/metastats/utils/constants.py +0 -0
  96. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/metastats/utils/io.py +0 -0
  97. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/metastats/utils/pyarrow_memory_estimation_function.py +0 -0
  98. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/metastats/utils/ray_utils.py +0 -0
  99. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/stats/__init__.py +0 -0
  100. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/stats/basic.py +0 -0
  101. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/stats/models/__init__.py +0 -0
  102. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/stats/models/delta_column_stats.py +0 -0
  103. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/stats/models/delta_stats.py +0 -0
  104. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/stats/models/delta_stats_cache_result.py +0 -0
  105. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/stats/models/manifest_entry_stats.py +0 -0
  106. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/stats/models/stats_result.py +0 -0
  107. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/stats/types.py +0 -0
  108. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/stats/utils/__init__.py +0 -0
  109. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/stats/utils/intervals.py +0 -0
  110. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/stats/utils/io.py +0 -0
  111. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/compute/stats/utils/manifest_stats_file.py +0 -0
  112. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/constants.py +0 -0
  113. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/exceptions.py +0 -0
  114. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/io/__init__.py +0 -0
  115. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/io/aws/__init__.py +0 -0
  116. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/io/aws/redshift/__init__.py +0 -0
  117. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/io/aws/redshift/redshift_datasource.py +0 -0
  118. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/io/dataset.py +0 -0
  119. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/io/file_object_store.py +0 -0
  120. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/io/memcached_object_store.py +0 -0
  121. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/io/object_store.py +0 -0
  122. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/io/ray_plasma_object_store.py +0 -0
  123. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/io/read_api.py +0 -0
  124. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/io/redis_object_store.py +0 -0
  125. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/io/s3_object_store.py +0 -0
  126. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/logs.py +0 -0
  127. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/storage/__init__.py +0 -0
  128. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/storage/interface.py +0 -0
  129. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/storage/model/__init__.py +0 -0
  130. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/storage/model/delete_parameters.py +0 -0
  131. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/storage/model/delta.py +0 -0
  132. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/storage/model/list_result.py +0 -0
  133. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/storage/model/locator.py +0 -0
  134. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/storage/model/namespace.py +0 -0
  135. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/storage/model/partition.py +0 -0
  136. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/storage/model/sort_key.py +0 -0
  137. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/storage/model/stream.py +0 -0
  138. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/storage/model/table.py +0 -0
  139. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/storage/model/table_version.py +0 -0
  140. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/storage/model/types.py +0 -0
  141. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/__init__.py +0 -0
  142. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/aws/__init__.py +0 -0
  143. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/aws/test_clients.py +0 -0
  144. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/catalog/__init__.py +0 -0
  145. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/catalog/test_default_catalog_impl.py +0 -0
  146. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/compute/__init__.py +0 -0
  147. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/compute/compact_partition_rebase_then_incremental_test_cases.py +0 -0
  148. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/compute/compact_partition_test_cases.py +0 -0
  149. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/compute/compactor/__init__.py +0 -0
  150. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/compute/compactor/steps/__init__.py +0 -0
  151. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/compute/compactor/steps/test_repartition.py +0 -0
  152. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/compute/compactor/utils/__init__.py +0 -0
  153. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/compute/compactor/utils/test_io.py +0 -0
  154. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/compute/compactor_v2/__init__.py +0 -0
  155. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/compute/compactor_v2/test_compaction_session.py +0 -0
  156. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/compute/compactor_v2/test_hashlib.py +0 -0
  157. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/compute/compactor_v2/utils/__init__.py +0 -0
  158. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/compute/compactor_v2/utils/test_task_options.py +0 -0
  159. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/compute/test_compact_partition_incremental.py +0 -0
  160. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/compute/test_compact_partition_params.py +0 -0
  161. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/compute/test_compact_partition_rebase_then_incremental.py +0 -0
  162. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/compute/test_util_common.py +0 -0
  163. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/compute/test_util_constant.py +0 -0
  164. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/compute/test_util_create_table_deltas_repo.py +0 -0
  165. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/io/__init__.py +0 -0
  166. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/io/test_cloudpickle_bug_fix.py +0 -0
  167. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/io/test_file_object_store.py +0 -0
  168. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/io/test_memcached_object_store.py +0 -0
  169. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/io/test_ray_plasma_object_store.py +0 -0
  170. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/io/test_redis_object_store.py +0 -0
  171. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/io/test_s3_object_store.py +0 -0
  172. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/local_deltacat_storage/__init__.py +0 -0
  173. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/stats/__init__.py +0 -0
  174. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/stats/test_intervals.py +0 -0
  175. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/test_logs.py +0 -0
  176. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/test_utils/__init__.py +0 -0
  177. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/test_utils/constants.py +0 -0
  178. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/test_utils/pyarrow.py +0 -0
  179. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/test_utils/storage.py +0 -0
  180. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/test_utils/utils.py +0 -0
  181. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/utils/__init__.py +0 -0
  182. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/utils/data/__init__.py +0 -0
  183. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/utils/test_cloudpickle.py +0 -0
  184. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/utils/test_daft.py +0 -0
  185. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/utils/test_metrics.py +0 -0
  186. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/utils/test_placement.py +0 -0
  187. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/utils/test_pyarrow.py +0 -0
  188. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/utils/test_record_batch_tables.py +0 -0
  189. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/tests/utils/test_resources.py +0 -0
  190. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/types/__init__.py +0 -0
  191. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/types/media.py +0 -0
  192. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/types/partial_download.py +0 -0
  193. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/types/tables.py +0 -0
  194. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/utils/__init__.py +0 -0
  195. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/utils/arguments.py +0 -0
  196. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/utils/cloudpickle.py +0 -0
  197. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/utils/common.py +0 -0
  198. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/utils/daft.py +0 -0
  199. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/utils/metrics.py +0 -0
  200. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/utils/numpy.py +0 -0
  201. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/utils/pandas.py +0 -0
  202. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/utils/performance.py +0 -0
  203. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/utils/placement.py +0 -0
  204. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/utils/pyarrow.py +0 -0
  205. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/utils/ray_utils/__init__.py +0 -0
  206. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/utils/ray_utils/collections.py +0 -0
  207. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/utils/ray_utils/concurrency.py +0 -0
  208. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/utils/ray_utils/dataset.py +0 -0
  209. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/utils/ray_utils/performance.py +0 -0
  210. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/utils/ray_utils/runtime.py +0 -0
  211. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/utils/resources.py +0 -0
  212. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/utils/s3fs.py +0 -0
  213. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat/utils/schema.py +0 -0
  214. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat.egg-info/SOURCES.txt +0 -0
  215. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat.egg-info/dependency_links.txt +0 -0
  216. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat.egg-info/requires.txt +0 -0
  217. {deltacat-1.1.5 → deltacat-1.1.6}/deltacat.egg-info/top_level.txt +0 -0
  218. {deltacat-1.1.5 → deltacat-1.1.6}/setup.cfg +0 -0
  219. {deltacat-1.1.5 → deltacat-1.1.6}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: deltacat
3
- Version: 1.1.5
3
+ Version: 1.1.6
4
4
  Summary: A scalable, fast, ACID-compliant Data Catalog powered by Ray.
5
5
  Home-page: https://github.com/ray-project/deltacat
6
6
  Author: Ray Team
@@ -44,7 +44,7 @@ from deltacat.types.tables import TableWriteMode
44
44
 
45
45
  deltacat.logs.configure_deltacat_logger(logging.getLogger(__name__))
46
46
 
47
- __version__ = "1.1.5"
47
+ __version__ = "1.1.6"
48
48
 
49
49
 
50
50
  __all__ = [
@@ -1,8 +1,10 @@
1
- from typing import List
1
+ from typing import List, Set
2
2
 
3
3
  from deltacat.utils.common import env_integer, env_string
4
4
 
5
5
  DAFT_MAX_S3_CONNECTIONS_PER_FILE = env_integer("DAFT_MAX_S3_CONNECTIONS_PER_FILE", 8)
6
6
  BOTO_MAX_RETRIES = env_integer("BOTO_MAX_RETRIES", 5)
7
7
  TIMEOUT_ERROR_CODES: List[str] = ["ReadTimeoutError", "ConnectTimeoutError"]
8
+ RETRYABLE_PUT_OBJECT_ERROR_CODES: Set[str] = {"Throttling", "SlowDown"}
8
9
  AWS_REGION = env_string("AWS_REGION", "us-east-1")
10
+ RETRY_STOP_AFTER_DELAY = env_integer("RETRY_STOP_AFTER_DELAY", 10 * 60)
@@ -4,14 +4,18 @@ from functools import partial
4
4
  from typing import Any, Callable, Dict, Generator, List, Optional, Union
5
5
  from uuid import uuid4
6
6
  from botocore.config import Config
7
- from deltacat.aws.constants import BOTO_MAX_RETRIES
7
+ from deltacat.aws.constants import (
8
+ BOTO_MAX_RETRIES,
9
+ RETRY_STOP_AFTER_DELAY,
10
+ RETRYABLE_PUT_OBJECT_ERROR_CODES,
11
+ )
8
12
 
9
13
  import pyarrow as pa
10
14
  import ray
11
15
  import s3fs
12
16
  from boto3.resources.base import ServiceResource
13
17
  from botocore.client import BaseClient
14
- from botocore.exceptions import ClientError
18
+ from botocore.exceptions import ClientError, NoCredentialsError
15
19
  from ray.data.block import Block, BlockAccessor, BlockMetadata
16
20
  from ray.data.datasource import BlockWritePathProvider
17
21
  from ray.types import ObjectRef
@@ -315,7 +319,6 @@ def upload_sliced_table(
315
319
  **s3_client_kwargs,
316
320
  )
317
321
  manifest_entries.extend(slice_entries)
318
-
319
322
  return manifest_entries
320
323
 
321
324
 
@@ -504,41 +507,85 @@ def download_manifest_entries_distributed(
504
507
 
505
508
  def upload(s3_url: str, body, **s3_client_kwargs) -> Dict[str, Any]:
506
509
 
507
- # TODO (pdames): add tenacity retrying
508
510
  parsed_s3_url = parse_s3_url(s3_url)
509
511
  s3 = s3_client_cache(None, **s3_client_kwargs)
510
- return s3.put_object(
511
- Body=body,
512
- Bucket=parsed_s3_url.bucket,
513
- Key=parsed_s3_url.key,
512
+ retrying = Retrying(
513
+ wait=wait_random_exponential(multiplier=1, max=15),
514
+ stop=stop_after_delay(RETRY_STOP_AFTER_DELAY),
515
+ retry=retry_if_exception_type(RetryableError),
516
+ )
517
+ return retrying(
518
+ _put_object,
519
+ s3,
520
+ body,
521
+ parsed_s3_url.bucket,
522
+ parsed_s3_url.key,
514
523
  )
515
524
 
516
525
 
526
+ def _put_object(
527
+ s3_client, body: Any, bucket: str, key: str, **s3_put_object_kwargs
528
+ ) -> Dict[str, Any]:
529
+ try:
530
+ return s3_client.put_object(
531
+ Body=body, Bucket=bucket, Key=key, **s3_put_object_kwargs
532
+ )
533
+ except ClientError as e:
534
+ if e.response["Error"]["Code"] in RETRYABLE_PUT_OBJECT_ERROR_CODES:
535
+ raise RetryableError(
536
+ f"Retry upload for: {bucket}/{key} after receiving {e.response['Error']['Code']}"
537
+ ) from e
538
+ raise NonRetryableError(f"Failed table upload to: {bucket}/{key}") from e
539
+ except NoCredentialsError as e:
540
+ raise RetryableError(
541
+ f"Failed to fetch credentials when putting object into: {bucket}/{key}"
542
+ ) from e
543
+ except BaseException as e:
544
+ logger.error(
545
+ f"Upload has failed for {bucket}/{key}. Error: {e}",
546
+ exc_info=True,
547
+ )
548
+ raise NonRetryableError(f"Failed table upload to: {bucket}/{key}") from e
549
+
550
+
517
551
  def download(
518
552
  s3_url: str, fail_if_not_found: bool = True, **s3_client_kwargs
519
553
  ) -> Optional[Dict[str, Any]]:
520
554
 
521
- # TODO (pdames): add tenacity retrying
522
555
  parsed_s3_url = parse_s3_url(s3_url)
523
556
  s3 = s3_client_cache(None, **s3_client_kwargs)
557
+ retrying = Retrying(
558
+ wait=wait_random_exponential(multiplier=1, max=15),
559
+ stop=stop_after_delay(RETRY_STOP_AFTER_DELAY),
560
+ retry=retry_if_exception_type(RetryableError),
561
+ )
562
+ return retrying(
563
+ _get_object,
564
+ s3,
565
+ parsed_s3_url.bucket,
566
+ parsed_s3_url.key,
567
+ fail_if_not_found=fail_if_not_found,
568
+ )
569
+
570
+
571
+ def _get_object(s3_client, bucket: str, key: str, fail_if_not_found: bool = True):
524
572
  try:
525
- return s3.get_object(
526
- Bucket=parsed_s3_url.bucket,
527
- Key=parsed_s3_url.key,
573
+ return s3_client.get_object(
574
+ Bucket=bucket,
575
+ Key=key,
528
576
  )
529
577
  except ClientError as e:
530
- if fail_if_not_found:
531
- raise
532
- else:
533
- if e.response["Error"]["Code"] != "404":
534
- if e.response["Error"]["Code"] != "NoSuchKey":
535
- raise
536
- logger.info(f"file not found: {s3_url}")
537
- except s3.exceptions.NoSuchKey:
538
- if fail_if_not_found:
539
- raise
540
- else:
541
- logger.info(f"file not found: {s3_url}")
578
+ if e.response["Error"]["Code"] == "NoSuchKey":
579
+ if fail_if_not_found:
580
+ raise NonRetryableError(
581
+ f"Failed get object from: {bucket}/{key}"
582
+ ) from e
583
+ logger.info(f"file not found: {bucket}/{key}")
584
+ except NoCredentialsError as e:
585
+ raise RetryableError(
586
+ f"Failed to fetch credentials when getting object from: {bucket}/{key}"
587
+ ) from e
588
+
542
589
  return None
543
590
 
544
591
 
@@ -20,7 +20,6 @@ from deltacat.compute.compactor_v2.utils.primary_key_index import (
20
20
  from deltacat.compute.compactor_v2.constants import (
21
21
  PARQUET_TO_PYARROW_INFLATION,
22
22
  )
23
-
24
23
  from daft.exceptions import DaftTransientError
25
24
 
26
25
 
@@ -65,7 +64,11 @@ def get_task_options(
65
64
  cpu: float, memory: float, ray_custom_resources: Optional[Dict] = None
66
65
  ) -> Dict:
67
66
 
68
- task_opts = {"num_cpus": cpu, "memory": memory}
67
+ # NOTE: With DEFAULT scheduling strategy in Ray 2.20.0, autoscaler does
68
+ # not spin up enough nodes fast and hence we see only approximately
69
+ # 20 tasks get scheduled out of 100 tasks in queue.
70
+ # https://docs.ray.io/en/latest/ray-core/scheduling/index.html
71
+ task_opts = {"num_cpus": cpu, "memory": memory, "scheduling_strategy": "SPREAD"}
69
72
 
70
73
  if ray_custom_resources:
71
74
  task_opts["resources"] = ray_custom_resources
@@ -0,0 +1,124 @@
1
+ import unittest
2
+ from deltacat.aws.s3u import UuidBlockWritePathProvider, CapturedBlockWritePaths
3
+
4
+
5
+ import os
6
+ from unittest import mock
7
+ from unittest.mock import patch
8
+
9
+ import boto3
10
+ import pytest
11
+ from boto3.resources.base import ServiceResource
12
+ from botocore.exceptions import ClientError, NoCredentialsError
13
+ from deltacat.exceptions import NonRetryableError
14
+ from moto import mock_s3
15
+ from tenacity import RetryError
16
+
17
+ from deltacat.aws import s3u
18
+
19
+
20
+ class TestUuidBlockWritePathProvider(unittest.TestCase):
21
+ def test_uuid_block_write_provider_sanity(self):
22
+ capture_object = CapturedBlockWritePaths()
23
+ provider = UuidBlockWritePathProvider(capture_object=capture_object)
24
+
25
+ result = provider("base_path")
26
+
27
+ self.assertRegex(result, r"^base_path/[\w-]{36}$")
28
+
29
+
30
+ class TestDownloadUpload(unittest.TestCase):
31
+ TEST_S3_BUCKET_NAME = "TEST_S3_BUCKET"
32
+ TEST_S3_KEY = "TEST_S3_KEY"
33
+
34
+ @pytest.fixture(autouse=True)
35
+ def mock_aws_credential(self):
36
+ os.environ["AWS_ACCESS_KEY_ID"] = "testing"
37
+ os.environ["AWS_SECRET_ACCESS_ID"] = "testing"
38
+ os.environ["AWS_SECURITY_TOKEN"] = "testing"
39
+ os.environ["AWS_SESSION_TOKEN"] = "testing"
40
+ os.environ["AWS_DEFAULT_REGION"] = "us-east-1"
41
+ yield
42
+
43
+ @pytest.fixture(autouse=True)
44
+ def setup_s3_resource(self):
45
+ with mock_s3():
46
+ yield boto3.resource("s3")
47
+
48
+ @pytest.fixture(autouse=True)
49
+ def setup_test_s3_bucket(self, setup_s3_resource: ServiceResource):
50
+ setup_s3_resource.create_bucket(
51
+ ACL="authenticated-read",
52
+ Bucket=self.TEST_S3_BUCKET_NAME,
53
+ )
54
+ yield
55
+
56
+ def test_sanity(self):
57
+ uri = f"s3://{self.TEST_S3_BUCKET_NAME}/{self.TEST_S3_KEY}"
58
+ body = "test-body"
59
+ uploaded_file = s3u.upload(uri, body)
60
+ assert uploaded_file is not None
61
+ assert uploaded_file["ResponseMetadata"]["HTTPStatusCode"] == 200
62
+ downloaded_file = s3u.download(uri)
63
+ downloaded_body = downloaded_file["Body"].read().decode("utf-8")
64
+ assert downloaded_file["ResponseMetadata"]["HTTPStatusCode"] == 200
65
+ assert downloaded_body == body
66
+
67
+ @patch("deltacat.aws.s3u.RETRY_STOP_AFTER_DELAY", 1)
68
+ @patch("deltacat.aws.s3u.s3_client_cache")
69
+ def test_upload_throttled(self, mock_s3_client_cache):
70
+ uri = f"s3://{self.TEST_S3_BUCKET_NAME}/{self.TEST_S3_KEY}"
71
+ body = "test-body"
72
+ throttling_err = ClientError({"Error": {"Code": "Throttling"}}, "put_object")
73
+ mock_s3_client_cache.return_value = mock_s3 = mock.MagicMock()
74
+ mock_s3.put_object.side_effect = throttling_err
75
+ with pytest.raises(RetryError):
76
+ s3u.upload(uri, body)
77
+
78
+ slowdown_err = ClientError({"Error": {"Code": "SlowDown"}}, "put_object")
79
+ mock_s3.put_object.side_effect = slowdown_err
80
+ with pytest.raises(RetryError):
81
+ s3u.upload(uri, body)
82
+
83
+ no_credentials_err = NoCredentialsError()
84
+ mock_s3.put_object.side_effect = no_credentials_err
85
+ with pytest.raises(RetryError):
86
+ s3u.upload(uri, body)
87
+
88
+ assert mock_s3.put_object.call_count > 3
89
+
90
+ @patch("deltacat.aws.s3u.s3_client_cache")
91
+ def test_upload_unexpected_error_code(self, mock_s3_client_cache):
92
+ uri = f"s3://{self.TEST_S3_BUCKET_NAME}/{self.TEST_S3_KEY}"
93
+ body = "test-body"
94
+ err = ClientError({"Error": {"Code": "UnexpectedError"}}, "put_object")
95
+ mock_s3_client_cache.return_value = mock_s3 = mock.MagicMock()
96
+ mock_s3.put_object.side_effect = err
97
+ file = None
98
+ with pytest.raises(NonRetryableError):
99
+ s3u.upload(uri, body)
100
+ assert file is None
101
+ assert mock_s3.put_object.call_count == 1
102
+
103
+ @patch("deltacat.aws.s3u.RETRY_STOP_AFTER_DELAY", 1)
104
+ @patch("deltacat.aws.s3u.s3_client_cache")
105
+ def test_download_throttled(self, mock_s3_client_cache):
106
+ uri = f"s3://{self.TEST_S3_BUCKET_NAME}/{self.TEST_S3_KEY}"
107
+ no_credentials_err = NoCredentialsError()
108
+ mock_s3_client_cache.return_value = mock_s3 = mock.MagicMock()
109
+ mock_s3.get_object.side_effect = no_credentials_err
110
+ file = None
111
+ with pytest.raises(RetryError):
112
+ file = s3u.download(uri)
113
+ assert file is None
114
+ assert mock_s3.get_object.call_count > 1
115
+
116
+ def test_download_not_exists(self):
117
+ uri = f"s3://{self.TEST_S3_BUCKET_NAME}/key-not-exists"
118
+ file = None
119
+ with pytest.raises(NonRetryableError):
120
+ file = s3u.download(uri)
121
+ assert file is None
122
+
123
+ file = s3u.download(uri, fail_if_not_found=False)
124
+ assert file is None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: deltacat
3
- Version: 1.1.5
3
+ Version: 1.1.6
4
4
  Summary: A scalable, fast, ACID-compliant Data Catalog powered by Ray.
5
5
  Home-page: https://github.com/ray-project/deltacat
6
6
  Author: Ray Team
@@ -1,12 +0,0 @@
1
- import unittest
2
- from deltacat.aws.s3u import UuidBlockWritePathProvider, CapturedBlockWritePaths
3
-
4
-
5
- class TestUuidBlockWritePathProvider(unittest.TestCase):
6
- def test_uuid_block_write_provider_sanity(self):
7
- capture_object = CapturedBlockWritePaths()
8
- provider = UuidBlockWritePathProvider(capture_object=capture_object)
9
-
10
- result = provider("base_path")
11
-
12
- self.assertRegex(result, r"^base_path/[\w-]{36}$")
File without changes
File without changes
File without changes