pixeltable 0.4.2__tar.gz → 0.4.3__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.

Potentially problematic release.


This version of pixeltable might be problematic. Click here for more details.

Files changed (196) hide show
  1. {pixeltable-0.4.2 → pixeltable-0.4.3}/PKG-INFO +1 -1
  2. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/__init__.py +1 -0
  3. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/__version__.py +2 -2
  4. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/__init__.py +2 -10
  5. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/catalog.py +64 -38
  6. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/column.py +22 -23
  7. pixeltable-0.4.3/pixeltable/catalog/globals.py +88 -0
  8. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/insertable_table.py +6 -4
  9. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/path.py +6 -0
  10. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/table.py +51 -32
  11. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/table_version.py +69 -45
  12. pixeltable-0.4.2/pixeltable/catalog/globals.py → pixeltable-0.4.3/pixeltable/catalog/update_status.py +40 -95
  13. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/view.py +9 -2
  14. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/config.py +76 -12
  15. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/dataframe.py +1 -1
  16. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/env.py +29 -0
  17. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/exec_node.py +7 -24
  18. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/expr_eval/schedulers.py +134 -7
  19. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/column_property_ref.py +21 -9
  20. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/column_ref.py +5 -1
  21. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/function_call.py +2 -2
  22. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/row_builder.py +10 -9
  23. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/rowid_ref.py +0 -4
  24. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/function.py +3 -3
  25. pixeltable-0.4.3/pixeltable/functions/audio.py +57 -0
  26. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/video.py +57 -10
  27. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/globals.py +61 -1
  28. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/io/__init__.py +1 -1
  29. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/io/external_store.py +3 -55
  30. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/io/globals.py +4 -4
  31. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/io/hf_datasets.py +10 -2
  32. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/io/label_studio.py +16 -16
  33. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/__init__.py +1 -1
  34. pixeltable-0.4.3/pixeltable/metadata/converters/convert_39.py +125 -0
  35. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/util.py +3 -0
  36. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/notes.py +1 -0
  37. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/schema.py +14 -2
  38. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/plan.py +4 -0
  39. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/share/packager.py +20 -38
  40. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/store.py +18 -50
  41. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/type_system.py +2 -2
  42. pixeltable-0.4.3/pixeltable/utils/coroutine.py +24 -0
  43. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/media_store.py +39 -0
  44. {pixeltable-0.4.2 → pixeltable-0.4.3}/pyproject.toml +1 -1
  45. pixeltable-0.4.2/pixeltable/functions/audio.py +0 -30
  46. pixeltable-0.4.2/pixeltable/utils/coroutine.py +0 -41
  47. {pixeltable-0.4.2 → pixeltable-0.4.3}/LICENSE +0 -0
  48. {pixeltable-0.4.2 → pixeltable-0.4.3}/README.md +0 -0
  49. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/dir.py +0 -0
  50. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/named_function.py +0 -0
  51. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/schema_object.py +0 -0
  52. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/table_version_handle.py +0 -0
  53. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/table_version_path.py +0 -0
  54. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exceptions.py +0 -0
  55. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/__init__.py +0 -0
  56. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/aggregation_node.py +0 -0
  57. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/cache_prefetch_node.py +0 -0
  58. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/component_iteration_node.py +0 -0
  59. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/data_row_batch.py +0 -0
  60. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/exec_context.py +0 -0
  61. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/expr_eval/__init__.py +0 -0
  62. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/expr_eval/evaluators.py +0 -0
  63. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/expr_eval/expr_eval_node.py +0 -0
  64. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/expr_eval/globals.py +0 -0
  65. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/expr_eval/row_buffer.py +0 -0
  66. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/in_memory_data_node.py +0 -0
  67. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/row_update_node.py +0 -0
  68. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/sql_node.py +0 -0
  69. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/__init__.py +0 -0
  70. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/arithmetic_expr.py +0 -0
  71. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/array_slice.py +0 -0
  72. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/comparison.py +0 -0
  73. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/compound_predicate.py +0 -0
  74. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/data_row.py +0 -0
  75. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/expr.py +0 -0
  76. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/expr_dict.py +0 -0
  77. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/expr_set.py +0 -0
  78. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/globals.py +0 -0
  79. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/in_predicate.py +0 -0
  80. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/inline_expr.py +0 -0
  81. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/is_null.py +0 -0
  82. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/json_mapper.py +0 -0
  83. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/json_path.py +0 -0
  84. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/literal.py +0 -0
  85. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/method_ref.py +0 -0
  86. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/object_ref.py +0 -0
  87. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/similarity_expr.py +0 -0
  88. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/sql_element_cache.py +0 -0
  89. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/string_op.py +0 -0
  90. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/type_cast.py +0 -0
  91. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/variable.py +0 -0
  92. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/ext/__init__.py +0 -0
  93. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/ext/functions/__init__.py +0 -0
  94. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/ext/functions/whisperx.py +0 -0
  95. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/ext/functions/yolox.py +0 -0
  96. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/__init__.py +0 -0
  97. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/aggregate_function.py +0 -0
  98. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/callable_function.py +0 -0
  99. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/expr_template_function.py +0 -0
  100. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/function_registry.py +0 -0
  101. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/globals.py +0 -0
  102. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/mcp.py +0 -0
  103. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/query_template_function.py +0 -0
  104. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/signature.py +0 -0
  105. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/tools.py +0 -0
  106. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/udf.py +0 -0
  107. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/__init__.py +0 -0
  108. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/anthropic.py +0 -0
  109. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/bedrock.py +0 -0
  110. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/date.py +0 -0
  111. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/deepseek.py +0 -0
  112. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/fireworks.py +0 -0
  113. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/gemini.py +0 -0
  114. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/globals.py +0 -0
  115. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/groq.py +0 -0
  116. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/huggingface.py +0 -0
  117. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/image.py +0 -0
  118. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/json.py +0 -0
  119. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/llama_cpp.py +0 -0
  120. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/math.py +0 -0
  121. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/mistralai.py +0 -0
  122. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/ollama.py +0 -0
  123. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/openai.py +0 -0
  124. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/replicate.py +0 -0
  125. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/string.py +0 -0
  126. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/timestamp.py +0 -0
  127. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/together.py +0 -0
  128. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/util.py +0 -0
  129. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/vision.py +0 -0
  130. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/whisper.py +0 -0
  131. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/index/__init__.py +0 -0
  132. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/index/base.py +0 -0
  133. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/index/btree.py +0 -0
  134. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/index/embedding_index.py +0 -0
  135. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/io/datarows.py +0 -0
  136. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/io/fiftyone.py +0 -0
  137. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/io/pandas.py +0 -0
  138. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/io/parquet.py +0 -0
  139. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/io/table_data_conduit.py +0 -0
  140. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/io/utils.py +0 -0
  141. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/iterators/__init__.py +0 -0
  142. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/iterators/audio.py +0 -0
  143. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/iterators/base.py +0 -0
  144. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/iterators/document.py +0 -0
  145. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/iterators/image.py +0 -0
  146. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/iterators/string.py +0 -0
  147. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/iterators/video.py +0 -0
  148. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_10.py +0 -0
  149. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_12.py +0 -0
  150. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_13.py +0 -0
  151. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_14.py +0 -0
  152. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_15.py +0 -0
  153. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_16.py +0 -0
  154. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_17.py +0 -0
  155. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_18.py +0 -0
  156. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_19.py +0 -0
  157. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_20.py +0 -0
  158. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_21.py +0 -0
  159. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_22.py +0 -0
  160. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_23.py +0 -0
  161. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_24.py +0 -0
  162. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_25.py +0 -0
  163. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_26.py +0 -0
  164. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_27.py +0 -0
  165. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_28.py +0 -0
  166. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_29.py +0 -0
  167. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_30.py +0 -0
  168. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_31.py +0 -0
  169. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_32.py +0 -0
  170. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_33.py +0 -0
  171. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_34.py +0 -0
  172. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_35.py +0 -0
  173. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_36.py +0 -0
  174. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_37.py +0 -0
  175. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_38.py +0 -0
  176. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/utils.py +0 -0
  177. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/py.typed +0 -0
  178. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/share/__init__.py +0 -0
  179. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/share/publish.py +0 -0
  180. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/__init__.py +0 -0
  181. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/arrow.py +0 -0
  182. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/coco.py +0 -0
  183. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/code.py +0 -0
  184. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/console_output.py +0 -0
  185. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/dbms.py +0 -0
  186. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/description_helper.py +0 -0
  187. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/documents.py +0 -0
  188. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/exception_handler.py +0 -0
  189. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/filecache.py +0 -0
  190. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/formatter.py +0 -0
  191. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/http_server.py +0 -0
  192. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/iceberg.py +0 -0
  193. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/pytorch.py +0 -0
  194. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/s3.py +0 -0
  195. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/sql.py +0 -0
  196. {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/transactional_directory.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pixeltable
3
- Version: 0.4.2
3
+ Version: 0.4.3
4
4
  Summary: AI Data Infrastructure: Declarative, Multimodal, and Incremental
5
5
  License: Apache-2.0
6
6
  Keywords: data-science,machine-learning,database,ai,computer-vision,chatbot,ml,artificial-intelligence,feature-engineering,multimodal,mlops,feature-store,vector-database,llm,genai
@@ -20,6 +20,7 @@ from .globals import (
20
20
  list_dirs,
21
21
  list_functions,
22
22
  list_tables,
23
+ ls,
23
24
  move,
24
25
  tool,
25
26
  tools,
@@ -1,3 +1,3 @@
1
1
  # These version placeholders will be replaced during build.
2
- __version__ = '0.4.2'
3
- __version_tuple__ = (0, 4, 2)
2
+ __version__ = '0.4.3'
3
+ __version_tuple__ = (0, 4, 3)
@@ -3,16 +3,7 @@
3
3
  from .catalog import Catalog
4
4
  from .column import Column
5
5
  from .dir import Dir
6
- from .globals import (
7
- IfExistsParam,
8
- IfNotExistsParam,
9
- MediaValidation,
10
- QColumnId,
11
- RowCountStats,
12
- UpdateStatus,
13
- is_valid_identifier,
14
- is_valid_path,
15
- )
6
+ from .globals import IfExistsParam, IfNotExistsParam, MediaValidation, QColumnId, is_valid_identifier, is_valid_path
16
7
  from .insertable_table import InsertableTable
17
8
  from .named_function import NamedFunction
18
9
  from .path import Path
@@ -21,4 +12,5 @@ from .table import Table
21
12
  from .table_version import TableVersion
22
13
  from .table_version_handle import ColumnHandle, TableVersionHandle
23
14
  from .table_version_path import TableVersionPath
15
+ from .update_status import RowCountStats, UpdateStatus
24
16
  from .view import View
@@ -766,56 +766,47 @@ class Catalog:
766
766
  self._tbls[view._id] = view
767
767
  return view
768
768
 
769
- @_retry_loop(for_write=True)
770
- def create_replica(
771
- self, path: Path, md: list[schema.FullTableMd], if_exists: IfExistsParam = IfExistsParam.ERROR
772
- ) -> None:
769
+ def create_replica(self, path: Path, md: list[schema.FullTableMd]) -> None:
773
770
  """
774
771
  Creates table, table_version, and table_schema_version records for a replica with the given metadata.
775
772
  The metadata should be presented in standard "ancestor order", with the table being replicated at
776
773
  list position 0 and the (root) base table at list position -1.
777
-
778
- TODO: create_replica() also needs to create the store tables and populate them in order to make
779
- replica creation atomic.
780
774
  """
775
+ assert Env.get().in_xact
776
+
781
777
  tbl_id = UUID(md[0].tbl_md.tbl_id)
782
778
 
783
- # First handle path collisions (if_exists='ignore' or 'replace' or etc).
784
- existing = self._handle_path_collision(path, View, False, if_exists)
785
- if existing is not None:
786
- if existing._id != tbl_id:
787
- raise excs.Error(
788
- f"An attempt was made to create a replica table at {path!r} with if_exists='ignore', "
789
- 'but a different table already exists at that location.'
790
- )
791
- assert isinstance(existing, View)
792
- return
779
+ existing = self._handle_path_collision(path, Table, False, if_exists=IfExistsParam.IGNORE) # type: ignore[type-abstract]
780
+ if existing is not None and existing._id != tbl_id:
781
+ raise excs.Error(
782
+ f'An attempt was made to create a replica table at {path!r}, '
783
+ 'but a different table already exists at that location.'
784
+ )
793
785
 
794
786
  # Ensure that the system directory exists.
795
787
  self._create_dir(Path('_system', allow_system_paths=True), if_exists=IfExistsParam.IGNORE, parents=False)
796
788
 
797
- # Now check to see if this table already exists in the catalog.
789
+ # Now check to see if this table UUID already exists in the catalog.
798
790
  existing = Catalog.get().get_table_by_id(tbl_id)
799
791
  if existing is not None:
800
792
  existing_path = Path(existing._path(), allow_system_paths=True)
801
- # It does exist. If it's a non-system table, that's an error: it's already been replicated.
802
- if not existing_path.is_system_path:
803
- raise excs.Error(
804
- f'That table has already been replicated as {existing._path()!r}. \n'
805
- f'Drop the existing replica if you wish to re-create it.'
806
- )
807
- # If it's a system table, then this means it was created at some point as the ancestor of some other
808
- # table (a snapshot-over-snapshot scenario). In that case, we simply move it to the new (named) location.
809
- self._move(existing_path, path)
810
-
811
- # Now store the metadata for this replica. In the case where the table already exists (and was just moved
812
- # into a named location), this will be a no-op, but it still serves to validate that the newly received
813
- # metadata is identical to what's in the catalog.
814
- self.__store_replica_md(path, md[0])
793
+ if existing_path != path:
794
+ # It does exist, under a different path from the specified one.
795
+ if not existing_path.is_system_path:
796
+ raise excs.Error(
797
+ f'That table has already been replicated as {existing_path!r}.\n'
798
+ f'Drop the existing replica if you wish to re-create it.'
799
+ )
800
+ # If it's a system table, then this means it was created at some point as the ancestor of some other
801
+ # table (a snapshot-over-snapshot scenario). In that case, we simply move it to the new (named)
802
+ # location.
803
+ self._move(existing_path, path)
815
804
 
816
- # Now store the metadata for all of this table's proper ancestors. If one or more proper ancestors
805
+ # Now store the metadata for this replica's proper ancestors. If one or more proper ancestors
817
806
  # do not yet exist in the store, they will be created as anonymous system tables.
818
- for ancestor_md in md[1:]:
807
+ # We instantiate the ancestors starting with the base table and ending with the immediate parent of the
808
+ # table being replicated.
809
+ for ancestor_md in md[:0:-1]:
819
810
  ancestor_id = UUID(ancestor_md.tbl_md.tbl_id)
820
811
  replica = Catalog.get().get_table_by_id(ancestor_id)
821
812
  replica_path: Path
@@ -828,12 +819,22 @@ class Catalog:
828
819
  # that was directly replicated by the user at some point). In either case, use the existing path.
829
820
  replica_path = Path(replica._path(), allow_system_paths=True)
830
821
 
831
- # Store the metadata; it could be a new version (in which case a new record will be created) or a
832
- # known version (in which case the newly received metadata will be validated as identical).
822
+ # Store the metadata; it could be a new version (in which case a new record will be created), or a known
823
+ # version (in which case the newly received metadata will be validated as identical).
824
+ # If it's a new version, this will result in a new TableVersion record being created.
833
825
  self.__store_replica_md(replica_path, ancestor_md)
834
826
 
835
- # don't create TableVersion instances at this point, they would be superseded by calls to TV.create_replica()
836
- # in TableRestorer.restore()
827
+ # Now we must clear cached metadata for the ancestor table, to force the next table operation to pick up
828
+ # the new TableVersion instance. This is necessary because computed columns of descendant tables might
829
+ # reference columns of the ancestor table that only exist in the new version.
830
+ replica = Catalog.get().get_table_by_id(ancestor_id)
831
+ assert replica is not None # If it didn't exist before, it must have been created by now.
832
+ replica._tbl_version_path.clear_cached_md()
833
+
834
+ # Finally, store the metadata for the table being replicated; as before, it could be a new version or a known
835
+ # version. If it's a new version, then a TableVersion record will be created, unless the table being replicated
836
+ # is a pure snapshot.
837
+ self.__store_replica_md(path, md[0])
837
838
 
838
839
  def __store_replica_md(self, path: Path, md: schema.FullTableMd) -> None:
839
840
  _logger.info(f'Creating replica table at {path!r} with ID: {md.tbl_md.tbl_id}')
@@ -917,10 +918,17 @@ class Catalog:
917
918
 
918
919
  self.store_tbl_md(UUID(tbl_id), None, new_tbl_md, new_version_md, new_schema_version_md)
919
920
 
921
+ if new_version_md is not None and not md.is_pure_snapshot:
922
+ # It's a new version of a table that has a physical store, so we need to create a TableVersion instance.
923
+ TableVersion.create_replica(md)
924
+
920
925
  @_retry_loop(for_write=False)
921
926
  def get_table(self, path: Path) -> Table:
922
927
  obj = Catalog.get()._get_schema_object(path, expected=Table, raise_if_not_exists=True)
923
928
  assert isinstance(obj, Table)
929
+ # We need to clear cached metadata from tbl_version_path, in case the schema has been changed
930
+ # by another process.
931
+ obj._tbl_version_path.clear_cached_md()
924
932
  return obj
925
933
 
926
934
  @_retry_loop(for_write=True)
@@ -1398,6 +1406,24 @@ class Catalog:
1398
1406
  session.add(schema_version_record)
1399
1407
  session.flush() # Inform SQLAlchemy that we want to write these changes to the DB.
1400
1408
 
1409
+ def update_tbl_version_md(self, version_md: Optional[schema.TableVersionMd]) -> None:
1410
+ """
1411
+ Update the TableVersion.md field in the DB. Typically used to update the cascade row count status.
1412
+
1413
+ Args:
1414
+ version_md: TableVersionMd
1415
+ """
1416
+ assert self._in_write_xact
1417
+ session = Env.get().session
1418
+
1419
+ session.execute(
1420
+ sql.update(schema.TableVersion.__table__)
1421
+ .values({schema.TableVersion.md: dataclasses.asdict(version_md)})
1422
+ .where(schema.TableVersion.tbl_id == version_md.tbl_id, schema.TableVersion.version == version_md.version)
1423
+ )
1424
+
1425
+ session.flush() # Inform SQLAlchemy that we want to write these changes to the DB.
1426
+
1401
1427
  def delete_tbl_md(self, tbl_id: UUID) -> None:
1402
1428
  """
1403
1429
  Deletes all table metadata from the store for the given table UUID.
@@ -36,11 +36,10 @@ class Column:
36
36
  _media_validation: Optional[MediaValidation] # if not set, TableVersion.media_validation applies
37
37
  schema_version_add: Optional[int]
38
38
  schema_version_drop: Optional[int]
39
- _records_errors: Optional[bool]
39
+ _stores_cellmd: Optional[bool]
40
40
  sa_col: Optional[sql.schema.Column]
41
41
  sa_col_type: Optional[sql.sqltypes.TypeEngine]
42
- sa_errormsg_col: Optional[sql.schema.Column]
43
- sa_errortype_col: Optional[sql.schema.Column]
42
+ sa_cellmd_col: Optional[sql.schema.Column] # JSON metadata for the cell, e.g. errortype, errormsg for media columns
44
43
  _value_expr: Optional[exprs.Expr]
45
44
  value_expr_dict: Optional[dict[str, Any]]
46
45
  # we store a TableVersion here, not a TableVersionHandle, because this column is owned by that TableVersion instance
@@ -59,7 +58,7 @@ class Column:
59
58
  schema_version_add: Optional[int] = None,
60
59
  schema_version_drop: Optional[int] = None,
61
60
  sa_col_type: Optional[sql.sqltypes.TypeEngine] = None,
62
- records_errors: Optional[bool] = None,
61
+ stores_cellmd: Optional[bool] = None,
63
62
  value_expr_dict: Optional[dict[str, Any]] = None,
64
63
  tbl: Optional[TableVersion] = None,
65
64
  ):
@@ -118,15 +117,14 @@ class Column:
118
117
  self.schema_version_add = schema_version_add
119
118
  self.schema_version_drop = schema_version_drop
120
119
 
121
- self._records_errors = records_errors
120
+ self._stores_cellmd = stores_cellmd
122
121
 
123
122
  # column in the stored table for the values of this Column
124
123
  self.sa_col = None
125
124
  self.sa_col_type = sa_col_type
126
125
 
127
126
  # computed cols also have storage columns for the exception string and type
128
- self.sa_errormsg_col = None
129
- self.sa_errortype_col = None
127
+ self.sa_cellmd_col = None
130
128
 
131
129
  def init_value_expr(self) -> None:
132
130
  from pixeltable import exprs
@@ -203,11 +201,11 @@ class Column:
203
201
  return self.stored
204
202
 
205
203
  @property
206
- def records_errors(self) -> bool:
204
+ def stores_cellmd(self) -> bool:
207
205
  """True if this column also stores error information."""
208
206
  # default: record errors for computed and media columns
209
- if self._records_errors is not None:
210
- return self._records_errors
207
+ if self._stores_cellmd is not None:
208
+ return self._stores_cellmd
211
209
  return self.is_stored and (self.is_computed or self.col_type.is_media_type())
212
210
 
213
211
  @property
@@ -243,28 +241,29 @@ class Column:
243
241
  """
244
242
  assert self.is_stored
245
243
  # all storage columns are nullable (we deal with null errors in Pixeltable directly)
246
- self.sa_col = sql.Column(
247
- self.store_name(),
248
- self.col_type.to_sa_type() if self.sa_col_type is None else self.sa_col_type,
249
- nullable=True,
250
- )
251
- if self.is_computed or self.col_type.is_media_type():
252
- self.sa_errormsg_col = sql.Column(self.errormsg_store_name(), ts.StringType().to_sa_type(), nullable=True)
253
- self.sa_errortype_col = sql.Column(self.errortype_store_name(), ts.StringType().to_sa_type(), nullable=True)
244
+ self.sa_col = sql.Column(self.store_name(), self.get_sa_col_type(), nullable=True)
245
+ if self.stores_cellmd:
246
+ # JSON metadata for the cell, e.g. errortype, errormsg for media columns
247
+ self.sa_cellmd_col = sql.Column(self.cellmd_store_name(), self.sa_cellmd_type(), nullable=True)
254
248
 
255
249
  def get_sa_col_type(self) -> sql.sqltypes.TypeEngine:
256
250
  return self.col_type.to_sa_type() if self.sa_col_type is None else self.sa_col_type
257
251
 
252
+ @classmethod
253
+ def cellmd_type(cls) -> ts.ColumnType:
254
+ return ts.JsonType(nullable=True)
255
+
256
+ @classmethod
257
+ def sa_cellmd_type(cls) -> sql.sqltypes.TypeEngine:
258
+ return cls.cellmd_type().to_sa_type()
259
+
258
260
  def store_name(self) -> str:
259
261
  assert self.id is not None
260
262
  assert self.is_stored
261
263
  return f'col_{self.id}'
262
264
 
263
- def errormsg_store_name(self) -> str:
264
- return f'{self.store_name()}_errormsg'
265
-
266
- def errortype_store_name(self) -> str:
267
- return f'{self.store_name()}_errortype'
265
+ def cellmd_store_name(self) -> str:
266
+ return f'{self.store_name()}_cellmd'
268
267
 
269
268
  def __str__(self) -> str:
270
269
  return f'{self.name}: {self.col_type}'
@@ -0,0 +1,88 @@
1
+ from __future__ import annotations
2
+
3
+ import enum
4
+ import itertools
5
+ import logging
6
+ from dataclasses import dataclass
7
+ from typing import Optional
8
+ from uuid import UUID
9
+
10
+ import pixeltable.exceptions as excs
11
+
12
+ _logger = logging.getLogger('pixeltable')
13
+
14
+ # name of the position column in a component view
15
+ _POS_COLUMN_NAME = 'pos'
16
+ _ROWID_COLUMN_NAME = '_rowid'
17
+
18
+ # Set of symbols that are predefined in the `InsertableTable` class (and are therefore not allowed as column names).
19
+ # This will be populated lazily to avoid circular imports.
20
+ _PREDEF_SYMBOLS: Optional[set[str]] = None
21
+
22
+
23
+ @dataclass(frozen=True)
24
+ class QColumnId:
25
+ """Qualified column id"""
26
+
27
+ tbl_id: UUID
28
+ col_id: int
29
+
30
+
31
+ class MediaValidation(enum.Enum):
32
+ ON_READ = 0
33
+ ON_WRITE = 1
34
+
35
+ @classmethod
36
+ def validated(cls, name: str, error_prefix: str) -> MediaValidation:
37
+ try:
38
+ return cls[name.upper()]
39
+ except KeyError:
40
+ val_strs = ', '.join(f'{s.lower()!r}' for s in cls.__members__)
41
+ raise excs.Error(f'{error_prefix} must be one of: [{val_strs}]') from None
42
+
43
+
44
+ class IfExistsParam(enum.Enum):
45
+ ERROR = 0
46
+ IGNORE = 1
47
+ REPLACE = 2
48
+ REPLACE_FORCE = 3
49
+
50
+ @classmethod
51
+ def validated(cls, param_val: str, param_name: str) -> IfExistsParam:
52
+ try:
53
+ return cls[param_val.upper()]
54
+ except KeyError:
55
+ val_strs = ', '.join(f'{s.lower()!r}' for s in cls.__members__)
56
+ raise excs.Error(f'{param_name} must be one of: [{val_strs}]') from None
57
+
58
+
59
+ class IfNotExistsParam(enum.Enum):
60
+ ERROR = 0
61
+ IGNORE = 1
62
+
63
+ @classmethod
64
+ def validated(cls, param_val: str, param_name: str) -> IfNotExistsParam:
65
+ try:
66
+ return cls[param_val.upper()]
67
+ except KeyError:
68
+ val_strs = ', '.join(f'{s.lower()!r}' for s in cls.__members__)
69
+ raise excs.Error(f'{param_name} must be one of: [{val_strs}]') from None
70
+
71
+
72
+ def is_valid_identifier(name: str, allow_system_identifiers: bool = False) -> bool:
73
+ return name.isidentifier() and (allow_system_identifiers or not name.startswith('_'))
74
+
75
+
76
+ def is_valid_path(path: str, empty_is_valid: bool, allow_system_paths: bool = False) -> bool:
77
+ if path == '':
78
+ return empty_is_valid
79
+ return all(is_valid_identifier(part, allow_system_paths) for part in path.split('.'))
80
+
81
+
82
+ def is_system_column_name(name: str) -> bool:
83
+ from pixeltable.catalog import InsertableTable, View
84
+
85
+ global _PREDEF_SYMBOLS # noqa: PLW0603
86
+ if _PREDEF_SYMBOLS is None:
87
+ _PREDEF_SYMBOLS = set(itertools.chain(dir(InsertableTable), dir(View)))
88
+ return name == _POS_COLUMN_NAME or name in _PREDEF_SYMBOLS
@@ -10,11 +10,12 @@ from pixeltable import exceptions as excs, type_system as ts
10
10
  from pixeltable.env import Env
11
11
  from pixeltable.utils.filecache import FileCache
12
12
 
13
- from .globals import MediaValidation, UpdateStatus
13
+ from .globals import MediaValidation
14
14
  from .table import Table
15
15
  from .table_version import TableVersion
16
16
  from .table_version_handle import TableVersionHandle
17
17
  from .table_version_path import TableVersionPath
18
+ from .update_status import UpdateStatus
18
19
 
19
20
  if TYPE_CHECKING:
20
21
  from pixeltable import exprs
@@ -106,6 +107,7 @@ class InsertableTable(Table):
106
107
 
107
108
  def _get_metadata(self) -> dict[str, Any]:
108
109
  md = super()._get_metadata()
110
+ md['base'] = None
109
111
  md['is_view'] = False
110
112
  md['is_snapshot'] = False
111
113
  return md
@@ -171,14 +173,14 @@ class InsertableTable(Table):
171
173
  from pixeltable.catalog import Catalog
172
174
  from pixeltable.io.table_data_conduit import DFTableDataConduit
173
175
 
174
- status = pxt.UpdateStatus()
175
176
  with Catalog.get().begin_xact(tbl=self._tbl_version_path, for_write=True, lock_mutable_tree=True):
176
177
  if isinstance(data_source, DFTableDataConduit):
177
- status = self._tbl_version.get().insert(
178
+ status = pxt.UpdateStatus()
179
+ status += self._tbl_version.get().insert(
178
180
  rows=None, df=data_source.pxt_df, print_stats=print_stats, fail_on_exception=fail_on_exception
179
181
  )
180
182
  else:
181
- status = UpdateStatus()
183
+ status = pxt.UpdateStatus()
182
184
  for row_batch in data_source.valid_row_batch():
183
185
  status += self._tbl_version.get().insert(
184
186
  rows=row_batch, df=None, print_stats=print_stats, fail_on_exception=fail_on_exception
@@ -77,5 +77,11 @@ class Path:
77
77
  def __str__(self) -> str:
78
78
  return '.'.join(self.components)
79
79
 
80
+ def __eq__(self, other: object) -> bool:
81
+ return isinstance(other, Path) and str(self) == str(other)
82
+
83
+ def __hash__(self) -> int:
84
+ return hash(str(self))
85
+
80
86
  def __lt__(self, other: Path) -> bool:
81
87
  return str(self) < str(other)