pixeltable 0.2.25__py3-none-any.whl → 0.3.0__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 pixeltable might be problematic. Click here for more details.

Files changed (97) hide show
  1. pixeltable/__init__.py +2 -2
  2. pixeltable/__version__.py +2 -2
  3. pixeltable/catalog/__init__.py +1 -1
  4. pixeltable/catalog/dir.py +6 -0
  5. pixeltable/catalog/globals.py +25 -0
  6. pixeltable/catalog/named_function.py +4 -0
  7. pixeltable/catalog/path_dict.py +37 -11
  8. pixeltable/catalog/schema_object.py +6 -0
  9. pixeltable/catalog/table.py +421 -231
  10. pixeltable/catalog/table_version.py +22 -8
  11. pixeltable/catalog/view.py +5 -7
  12. pixeltable/dataframe.py +439 -105
  13. pixeltable/env.py +19 -5
  14. pixeltable/exec/__init__.py +1 -1
  15. pixeltable/exec/exec_node.py +6 -7
  16. pixeltable/exec/expr_eval_node.py +1 -1
  17. pixeltable/exec/sql_node.py +92 -45
  18. pixeltable/exprs/__init__.py +1 -0
  19. pixeltable/exprs/arithmetic_expr.py +1 -1
  20. pixeltable/exprs/array_slice.py +1 -1
  21. pixeltable/exprs/column_property_ref.py +1 -1
  22. pixeltable/exprs/column_ref.py +29 -2
  23. pixeltable/exprs/comparison.py +1 -1
  24. pixeltable/exprs/compound_predicate.py +1 -1
  25. pixeltable/exprs/expr.py +12 -5
  26. pixeltable/exprs/expr_set.py +8 -0
  27. pixeltable/exprs/function_call.py +147 -39
  28. pixeltable/exprs/in_predicate.py +1 -1
  29. pixeltable/exprs/inline_expr.py +25 -5
  30. pixeltable/exprs/is_null.py +1 -1
  31. pixeltable/exprs/json_mapper.py +1 -1
  32. pixeltable/exprs/json_path.py +1 -1
  33. pixeltable/exprs/method_ref.py +1 -1
  34. pixeltable/exprs/row_builder.py +1 -1
  35. pixeltable/exprs/rowid_ref.py +1 -1
  36. pixeltable/exprs/similarity_expr.py +14 -7
  37. pixeltable/exprs/sql_element_cache.py +4 -0
  38. pixeltable/exprs/type_cast.py +2 -2
  39. pixeltable/exprs/variable.py +3 -0
  40. pixeltable/func/__init__.py +5 -4
  41. pixeltable/func/aggregate_function.py +151 -68
  42. pixeltable/func/callable_function.py +48 -16
  43. pixeltable/func/expr_template_function.py +64 -23
  44. pixeltable/func/function.py +195 -27
  45. pixeltable/func/function_registry.py +2 -1
  46. pixeltable/func/query_template_function.py +51 -9
  47. pixeltable/func/signature.py +64 -7
  48. pixeltable/func/tools.py +153 -0
  49. pixeltable/func/udf.py +57 -35
  50. pixeltable/functions/__init__.py +2 -2
  51. pixeltable/functions/anthropic.py +51 -4
  52. pixeltable/functions/gemini.py +85 -0
  53. pixeltable/functions/globals.py +54 -34
  54. pixeltable/functions/huggingface.py +10 -28
  55. pixeltable/functions/json.py +3 -8
  56. pixeltable/functions/math.py +67 -0
  57. pixeltable/functions/ollama.py +8 -8
  58. pixeltable/functions/openai.py +51 -4
  59. pixeltable/functions/timestamp.py +1 -1
  60. pixeltable/functions/video.py +3 -9
  61. pixeltable/functions/vision.py +1 -1
  62. pixeltable/globals.py +354 -80
  63. pixeltable/index/embedding_index.py +106 -34
  64. pixeltable/io/__init__.py +1 -1
  65. pixeltable/io/label_studio.py +1 -1
  66. pixeltable/io/parquet.py +39 -19
  67. pixeltable/iterators/document.py +12 -0
  68. pixeltable/metadata/__init__.py +1 -1
  69. pixeltable/metadata/converters/convert_16.py +2 -1
  70. pixeltable/metadata/converters/convert_17.py +2 -1
  71. pixeltable/metadata/converters/convert_22.py +17 -0
  72. pixeltable/metadata/converters/convert_23.py +35 -0
  73. pixeltable/metadata/converters/convert_24.py +56 -0
  74. pixeltable/metadata/converters/convert_25.py +19 -0
  75. pixeltable/metadata/converters/util.py +4 -2
  76. pixeltable/metadata/notes.py +4 -0
  77. pixeltable/metadata/schema.py +1 -0
  78. pixeltable/plan.py +128 -50
  79. pixeltable/store.py +1 -1
  80. pixeltable/type_system.py +196 -54
  81. pixeltable/utils/arrow.py +8 -3
  82. pixeltable/utils/description_helper.py +89 -0
  83. pixeltable/utils/documents.py +14 -0
  84. {pixeltable-0.2.25.dist-info → pixeltable-0.3.0.dist-info}/METADATA +30 -20
  85. pixeltable-0.3.0.dist-info/RECORD +155 -0
  86. {pixeltable-0.2.25.dist-info → pixeltable-0.3.0.dist-info}/WHEEL +1 -1
  87. pixeltable-0.3.0.dist-info/entry_points.txt +3 -0
  88. pixeltable/tool/create_test_db_dump.py +0 -311
  89. pixeltable/tool/create_test_video.py +0 -81
  90. pixeltable/tool/doc_plugins/griffe.py +0 -50
  91. pixeltable/tool/doc_plugins/mkdocstrings.py +0 -6
  92. pixeltable/tool/doc_plugins/templates/material/udf.html.jinja +0 -135
  93. pixeltable/tool/embed_udf.py +0 -9
  94. pixeltable/tool/mypy_plugin.py +0 -55
  95. pixeltable-0.2.25.dist-info/RECORD +0 -154
  96. pixeltable-0.2.25.dist-info/entry_points.txt +0 -3
  97. {pixeltable-0.2.25.dist-info → pixeltable-0.3.0.dist-info}/LICENSE +0 -0
@@ -9,6 +9,7 @@ import uuid
9
9
  from typing import TYPE_CHECKING, Any, Iterable, Iterator, Literal, Optional
10
10
  from uuid import UUID
11
11
 
12
+ import jsonschema.exceptions
12
13
  import sqlalchemy as sql
13
14
  import sqlalchemy.orm as orm
14
15
 
@@ -173,6 +174,14 @@ class TableVersion:
173
174
  def __hash__(self) -> int:
174
175
  return hash(self.id)
175
176
 
177
+ def _get_column(self, tbl_id: UUID, col_id: int) -> Column:
178
+ if self.id == tbl_id:
179
+ return self.cols_by_id[col_id]
180
+ else:
181
+ if self.base is None:
182
+ raise excs.Error(f'Unknown table id: {tbl_id}')
183
+ return self.base._get_column(tbl_id, col_id)
184
+
176
185
  def create_snapshot_copy(self) -> TableVersion:
177
186
  """Create a snapshot copy of this TableVersion"""
178
187
  assert not self.is_snapshot
@@ -335,7 +344,7 @@ class TableVersion:
335
344
  # instantiate index object
336
345
  cls_name = md.class_fqn.rsplit('.', 1)[-1]
337
346
  cls = getattr(index_module, cls_name)
338
- idx_col = self.cols_by_id[md.indexed_col_id]
347
+ idx_col = self._get_column(UUID(md.indexed_col_tbl_id), md.indexed_col_id)
339
348
  idx = cls.from_dict(idx_col, md.init_args)
340
349
 
341
350
  # fix up the sa column type of the index value and undo columns
@@ -457,7 +466,8 @@ class TableVersion:
457
466
  idx_cls = type(idx)
458
467
  idx_md = schema.IndexMd(
459
468
  id=idx_id, name=idx_name,
460
- indexed_col_id=col.id, index_val_col_id=val_col.id, index_val_undo_col_id=undo_col.id,
469
+ indexed_col_id=col.id, indexed_col_tbl_id=str(col.tbl.id),
470
+ index_val_col_id=val_col.id, index_val_undo_col_id=undo_col.id,
461
471
  schema_version_add=self.schema_version, schema_version_drop=None,
462
472
  class_fqn=idx_cls.__module__ + '.' + idx_cls.__name__, init_args=idx.as_dict())
463
473
  idx_info = self.IndexInfo(id=idx_id, name=idx_name, idx=idx, col=col, val_col=val_col, undo_col=undo_col)
@@ -485,7 +495,10 @@ class TableVersion:
485
495
  idx_md.schema_version_drop = self.schema_version
486
496
  assert idx_md.name in self.idxs_by_name
487
497
  idx_info = self.idxs_by_name[idx_md.name]
498
+ # remove this index entry from the active indexes (in memory)
499
+ # and the index metadata (in persistent table metadata)
488
500
  del self.idxs_by_name[idx_md.name]
501
+ del self.idx_md[idx_id]
489
502
 
490
503
  with Env.get().engine.begin() as conn:
491
504
  self._drop_columns([idx_info.val_col, idx_info.undo_col])
@@ -819,7 +832,7 @@ class TableVersion:
819
832
  if error_if_not_exists:
820
833
  raise excs.Error(f'batch_update(): {len(unmatched_rows)} row(s) not found')
821
834
  if insert_if_not_exists:
822
- insert_status = self.insert(unmatched_rows, None, print_stats=False, fail_on_exception=False)
835
+ insert_status = self.insert(unmatched_rows, None, conn=conn, print_stats=False, fail_on_exception=False)
823
836
  result += insert_status
824
837
  return result
825
838
 
@@ -846,10 +859,11 @@ class TableVersion:
846
859
  raise excs.Error(f'Column {col_name} is a primary key column and cannot be updated')
847
860
 
848
861
  # make sure that the value is compatible with the column type
862
+ value_expr: exprs.Expr
849
863
  try:
850
864
  # check if this is a literal
851
- value_expr: exprs.Expr = exprs.Literal(val, col_type=col.col_type)
852
- except TypeError:
865
+ value_expr = exprs.Literal(val, col_type=col.col_type)
866
+ except (TypeError, jsonschema.exceptions.ValidationError):
853
867
  if not allow_exprs:
854
868
  raise excs.Error(
855
869
  f'Column {col_name}: value {val!r} is not a valid literal for this column '
@@ -858,11 +872,11 @@ class TableVersion:
858
872
  value_expr = exprs.Expr.from_object(val)
859
873
  if value_expr is None:
860
874
  raise excs.Error(f'Column {col_name}: value {val!r} is not a recognized literal or expression')
861
- if not col.col_type.matches(value_expr.col_type):
862
- raise excs.Error((
875
+ if not col.col_type.is_supertype_of(value_expr.col_type, ignore_nullable=True):
876
+ raise excs.Error(
863
877
  f'Type of value {val!r} ({value_expr.col_type}) is not compatible with the type of column '
864
878
  f'{col_name} ({col.col_type})'
865
- ))
879
+ )
866
880
  update_targets[col] = value_expr
867
881
 
868
882
  return update_targets
@@ -16,7 +16,7 @@ from pixeltable.iterators import ComponentIterator
16
16
 
17
17
  from .catalog import Catalog
18
18
  from .column import Column
19
- from .globals import _POS_COLUMN_NAME, UpdateStatus, MediaValidation
19
+ from .globals import _POS_COLUMN_NAME, MediaValidation, UpdateStatus
20
20
  from .table import Table
21
21
  from .table_version import TableVersion
22
22
  from .table_version_path import TableVersionPath
@@ -59,7 +59,7 @@ class View(Table):
59
59
 
60
60
  # verify that filter can be evaluated in the context of the base
61
61
  if predicate is not None:
62
- if not predicate.is_bound_by(base):
62
+ if not predicate.is_bound_by([base]):
63
63
  raise excs.Error(f'Filter cannot be computed in the context of the base {base.tbl_name()}')
64
64
  # create a copy that we can modify and store
65
65
  predicate = predicate.copy()
@@ -69,7 +69,7 @@ class View(Table):
69
69
  if not col.is_computed:
70
70
  continue
71
71
  # make sure that the value can be computed in the context of the base
72
- if col.value_expr is not None and not col.value_expr.is_bound_by(base):
72
+ if col.value_expr is not None and not col.value_expr.is_bound_by([base]):
73
73
  raise excs.Error(
74
74
  f'Column {col.name}: value expression cannot be computed in the context of the base {base.tbl_name()}')
75
75
 
@@ -166,13 +166,11 @@ class View(Table):
166
166
  return view
167
167
 
168
168
  @classmethod
169
- def _verify_column(
170
- cls, col: Column, existing_column_names: set[str], existing_query_names: Optional[set[str]] = None
171
- ) -> None:
169
+ def _verify_column(cls, col: Column) -> None:
172
170
  # make sure that columns are nullable or have a default
173
171
  if not col.col_type.nullable and not col.is_computed:
174
172
  raise excs.Error(f'Column {col.name}: non-computed columns in views must be nullable')
175
- super()._verify_column(col, existing_column_names, existing_query_names)
173
+ super()._verify_column(col)
176
174
 
177
175
  @classmethod
178
176
  def _get_snapshot_path(cls, tbl_version_path: TableVersionPath) -> TableVersionPath: