pixeltable 0.3.11__py3-none-any.whl → 0.3.12__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 (35) hide show
  1. pixeltable/__init__.py +1 -1
  2. pixeltable/__version__.py +2 -2
  3. pixeltable/catalog/catalog.py +309 -59
  4. pixeltable/catalog/globals.py +5 -5
  5. pixeltable/catalog/insertable_table.py +2 -1
  6. pixeltable/catalog/path.py +13 -6
  7. pixeltable/catalog/table.py +8 -6
  8. pixeltable/catalog/table_version.py +100 -72
  9. pixeltable/catalog/view.py +4 -9
  10. pixeltable/exec/sql_node.py +0 -1
  11. pixeltable/exprs/json_path.py +1 -5
  12. pixeltable/func/__init__.py +1 -1
  13. pixeltable/func/aggregate_function.py +1 -1
  14. pixeltable/func/callable_function.py +1 -1
  15. pixeltable/func/expr_template_function.py +2 -2
  16. pixeltable/func/function.py +3 -4
  17. pixeltable/func/query_template_function.py +87 -4
  18. pixeltable/func/tools.py +1 -1
  19. pixeltable/globals.py +7 -2
  20. pixeltable/metadata/__init__.py +1 -1
  21. pixeltable/metadata/converters/convert_31.py +11 -0
  22. pixeltable/metadata/converters/convert_32.py +15 -0
  23. pixeltable/metadata/converters/convert_33.py +17 -0
  24. pixeltable/metadata/notes.py +3 -0
  25. pixeltable/metadata/schema.py +26 -1
  26. pixeltable/plan.py +2 -3
  27. pixeltable/share/packager.py +8 -24
  28. pixeltable/share/publish.py +20 -9
  29. pixeltable/store.py +7 -4
  30. pixeltable/utils/exception_handler.py +59 -0
  31. {pixeltable-0.3.11.dist-info → pixeltable-0.3.12.dist-info}/METADATA +1 -1
  32. {pixeltable-0.3.11.dist-info → pixeltable-0.3.12.dist-info}/RECORD +35 -31
  33. {pixeltable-0.3.11.dist-info → pixeltable-0.3.12.dist-info}/LICENSE +0 -0
  34. {pixeltable-0.3.11.dist-info → pixeltable-0.3.12.dist-info}/WHEEL +0 -0
  35. {pixeltable-0.3.11.dist-info → pixeltable-0.3.12.dist-info}/entry_points.txt +0 -0
pixeltable/globals.py CHANGED
@@ -616,9 +616,14 @@ def _extract_paths(
616
616
  matches = [name for name, entry in dir_entries.items() if entry.dir is not None]
617
617
  else:
618
618
  matches = [name for name, entry in dir_entries.items() if entry.table is not None]
619
+
620
+ # Filter out system paths
621
+ matches = [name for name in matches if catalog.is_valid_identifier(name)]
619
622
  result = [parent.append(name) for name in matches]
620
- for name, entry in [(name, entry) for name, entry in dir_entries.items() if len(entry.dir_entries) > 0]:
621
- result.extend(_extract_paths(entry.dir_entries, parent=parent.append(name), entry_type=entry_type))
623
+
624
+ for name, entry in dir_entries.items():
625
+ if len(entry.dir_entries) > 0 and catalog.is_valid_identifier(name):
626
+ result.extend(_extract_paths(entry.dir_entries, parent=parent.append(name), entry_type=entry_type))
622
627
  return result
623
628
 
624
629
 
@@ -16,7 +16,7 @@ _console_logger = ConsoleLogger(logging.getLogger('pixeltable'))
16
16
 
17
17
 
18
18
  # current version of the metadata; this is incremented whenever the metadata schema changes
19
- VERSION = 31
19
+ VERSION = 34
20
20
 
21
21
 
22
22
  def create_system_info(engine: sql.engine.Engine) -> None:
@@ -0,0 +1,11 @@
1
+ import sqlalchemy as sql
2
+
3
+ from pixeltable.metadata import register_converter
4
+
5
+
6
+ @register_converter(version=31)
7
+ def _(engine: sql.engine.Engine) -> None:
8
+ # Add a column "lock_dummy: int8" to the dirs table in the store
9
+ # This column is the target of an UPDATE operation to synchronize directory operations
10
+ with engine.begin() as conn:
11
+ conn.execute(sql.text('ALTER TABLE dirs ADD COLUMN lock_dummy int8'))
@@ -0,0 +1,15 @@
1
+ from uuid import UUID
2
+
3
+ import sqlalchemy as sql
4
+
5
+ from pixeltable.metadata import register_converter
6
+ from pixeltable.metadata.converters.util import convert_table_md
7
+
8
+
9
+ @register_converter(version=32)
10
+ def _(engine: sql.engine.Engine) -> None:
11
+ convert_table_md(engine, table_md_updater=__update_table_md)
12
+
13
+
14
+ def __update_table_md(table_md: dict, table_id: UUID) -> None:
15
+ table_md['is_replica'] = False
@@ -0,0 +1,17 @@
1
+ from uuid import UUID
2
+
3
+ import sqlalchemy as sql
4
+
5
+ from pixeltable.metadata import register_converter
6
+ from pixeltable.metadata.converters.util import convert_table_md
7
+
8
+
9
+ @register_converter(version=33)
10
+ def _(engine: sql.engine.Engine) -> None:
11
+ convert_table_md(engine, table_md_updater=__update_table_md)
12
+
13
+
14
+ def __update_table_md(table_md: dict, table_id: UUID) -> None:
15
+ """Set default value of 'is_pk' field in column metadata to False"""
16
+ for col_md in table_md['column_md'].values():
17
+ col_md['is_pk'] = False if col_md['is_pk'] is None else col_md['is_pk']
@@ -2,6 +2,9 @@
2
2
  # rather than as a comment, so that the existence of a description can be enforced by
3
3
  # the unit tests when new versions are added.
4
4
  VERSION_NOTES = {
5
+ 34: 'Set default value for is_pk field in column metadata to False',
6
+ 33: 'Add is_replica field to table metadata',
7
+ 32: 'Add the lock_dummy BIGINT column to the dirs table',
5
8
  31: 'Add table ids to metadata structs',
6
9
  30: 'Store default values and constant arguments as literals',
7
10
  29: 'Add user and additional_md fields to metadata structs',
@@ -1,7 +1,7 @@
1
1
  import dataclasses
2
2
  import typing
3
3
  import uuid
4
- from typing import Any, Optional, TypeVar, Union, get_type_hints
4
+ from typing import Any, NamedTuple, Optional, TypeVar, Union, get_type_hints
5
5
 
6
6
  import sqlalchemy as sql
7
7
  from sqlalchemy import BigInteger, ForeignKey, Integer, LargeBinary, orm
@@ -84,6 +84,8 @@ class Dir(Base):
84
84
  )
85
85
  parent_id: orm.Mapped[uuid.UUID] = orm.mapped_column(UUID(as_uuid=True), ForeignKey('dirs.id'), nullable=True)
86
86
  md: orm.Mapped[dict[str, Any]] = orm.mapped_column(JSONB, nullable=False) # DirMd
87
+ # This field is updated to synchronize database operations across multiple sessions
88
+ lock_dummy: orm.Mapped[int] = orm.mapped_column(BigInteger, nullable=True)
87
89
 
88
90
 
89
91
  @dataclasses.dataclass
@@ -155,6 +157,7 @@ class ViewMd:
155
157
  class TableMd:
156
158
  tbl_id: str # uuid.UUID
157
159
  name: str
160
+ is_replica: bool
158
161
 
159
162
  user: Optional[str]
160
163
 
@@ -286,3 +289,25 @@ class Function(Base):
286
289
  dir_id: orm.Mapped[uuid.UUID] = orm.mapped_column(UUID(as_uuid=True), ForeignKey('dirs.id'), nullable=True)
287
290
  md: orm.Mapped[dict[str, Any]] = orm.mapped_column(JSONB, nullable=False) # FunctionMd
288
291
  binary_obj: orm.Mapped[Optional[bytes]] = orm.mapped_column(LargeBinary, nullable=True)
292
+
293
+
294
+ class FullTableMd(NamedTuple):
295
+ tbl_md: TableMd
296
+ version_md: TableVersionMd
297
+ schema_version_md: TableSchemaVersionMd
298
+
299
+ def as_dict(self) -> dict[str, Any]:
300
+ return {
301
+ 'table_id': self.tbl_md.tbl_id,
302
+ 'table_md': dataclasses.asdict(self.tbl_md),
303
+ 'table_version_md': dataclasses.asdict(self.version_md),
304
+ 'table_schema_version_md': dataclasses.asdict(self.schema_version_md),
305
+ }
306
+
307
+ @classmethod
308
+ def from_dict(cls, data_dict: dict[str, Any]) -> 'FullTableMd':
309
+ return FullTableMd(
310
+ tbl_md=md_from_dict(TableMd, data_dict['table_md']),
311
+ version_md=md_from_dict(TableVersionMd, data_dict['table_version_md']),
312
+ schema_version_md=md_from_dict(TableSchemaVersionMd, data_dict['table_schema_version_md']),
313
+ )
pixeltable/plan.py CHANGED
@@ -768,8 +768,7 @@ class Planner:
768
768
  # - select list subexprs that aren't aggregates
769
769
  # - join clause subexprs
770
770
  # - subexprs of Where clause conjuncts that can't be run in SQL
771
- # - all grouping exprs, if any aggregate function call can't be run in SQL (in that case, they all have to be
772
- # run in Python)
771
+ # - all grouping exprs
773
772
  candidates = list(
774
773
  exprs.Expr.list_subexprs(
775
774
  analyzer.select_list,
@@ -784,7 +783,7 @@ class Planner:
784
783
  candidates.extend(
785
784
  exprs.Expr.subexprs(analyzer.filter, filter=sql_elements.contains, traverse_matches=False)
786
785
  )
787
- if is_python_agg and analyzer.group_by_clause is not None:
786
+ if analyzer.group_by_clause is not None:
788
787
  candidates.extend(
789
788
  exprs.Expr.list_subexprs(analyzer.group_by_clause, filter=sql_elements.contains, traverse_matches=False)
790
789
  )
@@ -1,4 +1,3 @@
1
- import dataclasses
2
1
  import io
3
2
  import json
4
3
  import logging
@@ -6,7 +5,6 @@ import tarfile
6
5
  import urllib.parse
7
6
  import urllib.request
8
7
  import uuid
9
- from datetime import datetime
10
8
  from pathlib import Path
11
9
  from typing import Any, Iterator, Optional
12
10
 
@@ -58,28 +56,14 @@ class TablePackager:
58
56
  self.tmp_dir = Path(Env.get().create_tmp_path())
59
57
  self.media_files = {}
60
58
 
61
- # Generate metadata
62
- self.md = {
63
- 'pxt_version': pxt.__version__,
64
- 'pxt_md_version': metadata.VERSION,
65
- 'md': {
66
- 'tables': [
67
- {
68
- 'table_id': str(t._tbl_version.id),
69
- # These are temporary; will replace with a better solution once the concurrency
70
- # changes to catalog have been merged
71
- 'table_md': dataclasses.asdict(t._tbl_version.get()._create_tbl_md()),
72
- 'table_version_md': dataclasses.asdict(
73
- t._tbl_version.get()._create_version_md(datetime.now().timestamp())
74
- ),
75
- 'table_schema_version_md': dataclasses.asdict(
76
- t._tbl_version.get()._create_schema_version_md(0)
77
- ),
78
- }
79
- for t in (table, *table._bases)
80
- ]
81
- },
82
- }
59
+ # Load metadata
60
+ with Env.get().begin_xact():
61
+ tbl_md = catalog.Catalog.get().load_replica_md(table)
62
+ self.md = {
63
+ 'pxt_version': pxt.__version__,
64
+ 'pxt_md_version': metadata.VERSION,
65
+ 'md': {'tables': [md.as_dict() for md in tbl_md]},
66
+ }
83
67
  if additional_md is not None:
84
68
  self.md.update(additional_md)
85
69
 
@@ -1,4 +1,3 @@
1
- import os
2
1
  import sys
3
2
  import urllib.parse
4
3
  import urllib.request
@@ -10,22 +9,22 @@ from tqdm import tqdm
10
9
  import pixeltable as pxt
11
10
  from pixeltable import exceptions as excs
12
11
  from pixeltable.env import Env
12
+ from pixeltable.metadata.schema import FullTableMd
13
13
  from pixeltable.utils import sha256sum
14
14
 
15
15
  from .packager import TablePackager
16
16
 
17
17
  # These URLs are abstracted out for now, but will be replaced with actual (hard-coded) URLs once the
18
18
  # pixeltable.com URLs are available.
19
- _PUBLISH_URL = os.environ.get('PIXELTABLE_PUBLISH_URL')
20
- _FINALIZE_URL = os.environ.get('PIXELTABLE_FINALIZE_URL')
19
+
20
+ PIXELTABLE_API_URL = 'https://internal-api.pixeltable.com'
21
21
 
22
22
 
23
23
  def publish_snapshot(dest_tbl_uri: str, src_tbl: pxt.Table) -> str:
24
24
  packager = TablePackager(src_tbl, additional_md={'table_uri': dest_tbl_uri})
25
- request_json = packager.md
26
- headers_json = {'X-api-key': Env.get().pxt_api_key}
27
-
28
- response = requests.post(_PUBLISH_URL, json=request_json, headers=headers_json)
25
+ request_json = packager.md | {'operation_type': 'publish_snapshot'}
26
+ headers_json = {'X-api-key': Env.get().pxt_api_key, 'Content-Type': 'application/json'}
27
+ response = requests.post(PIXELTABLE_API_URL, json=request_json, headers=headers_json)
29
28
  if response.status_code != 200:
30
29
  raise excs.Error(f'Error publishing snapshot: {response.text}')
31
30
  response_json = response.json()
@@ -47,14 +46,14 @@ def publish_snapshot(dest_tbl_uri: str, src_tbl: pxt.Table) -> str:
47
46
  Env.get().console_logger.info('Finalizing snapshot ...')
48
47
 
49
48
  finalize_request_json = {
49
+ 'operation_type': 'finalize_snapshot',
50
50
  'upload_id': upload_id,
51
51
  'datafile': bundle.name,
52
52
  'size': bundle.stat().st_size,
53
53
  'sha256': sha256sum(bundle), # Generate our own SHA for independent verification
54
54
  }
55
-
56
55
  # TODO: Use Pydantic for validation
57
- finalize_response = requests.post(_FINALIZE_URL, json=finalize_request_json, headers=headers_json)
56
+ finalize_response = requests.post(PIXELTABLE_API_URL, json=finalize_request_json, headers=headers_json)
58
57
  if finalize_response.status_code != 200:
59
58
  raise excs.Error(f'Error finalizing snapshot: {finalize_response.text}')
60
59
  finalize_response_json = finalize_response.json()
@@ -66,6 +65,18 @@ def publish_snapshot(dest_tbl_uri: str, src_tbl: pxt.Table) -> str:
66
65
  return confirmed_tbl_uri
67
66
 
68
67
 
68
+ def clone_snapshot(dest_tbl_uri: str) -> list[FullTableMd]:
69
+ headers_json = {'X-api-key': Env.get().pxt_api_key, 'Content-Type': 'application/json'}
70
+ clone_request_json = {'operation_type': 'clone_snapshot', 'table_uri': dest_tbl_uri}
71
+ response = requests.post(PIXELTABLE_API_URL, json=clone_request_json, headers=headers_json)
72
+ if response.status_code != 200:
73
+ raise excs.Error(f'Error cloning snapshot: {response.text}')
74
+ response_json = response.json()
75
+ if not isinstance(response_json, dict) or 'table_uri' not in response_json:
76
+ raise excs.Error(f'Unexpected response from server.\n{response_json}')
77
+ return [FullTableMd.from_dict(t) for t in response_json['md']['tables']]
78
+
79
+
69
80
  def _upload_bundle_to_s3(bundle: Path, parsed_location: urllib.parse.ParseResult) -> None:
70
81
  from pixeltable.utils.s3 import get_client
71
82
 
pixeltable/store.py CHANGED
@@ -16,6 +16,7 @@ from pixeltable import catalog, exceptions as excs, exprs
16
16
  from pixeltable.env import Env
17
17
  from pixeltable.exec import ExecNode
18
18
  from pixeltable.metadata import schema
19
+ from pixeltable.utils.exception_handler import run_cleanup
19
20
  from pixeltable.utils.media_store import MediaStore
20
21
  from pixeltable.utils.sql import log_explain, log_stmt
21
22
 
@@ -232,7 +233,6 @@ class StoreBase:
232
233
  assert col.tbl.id == self.tbl_version.id
233
234
  num_excs = 0
234
235
  num_rows = 0
235
-
236
236
  # create temp table to store output of exec_plan, with the same primary key as the store table
237
237
  tmp_name = f'temp_{self._storage_name()}'
238
238
  tmp_pk_cols = [sql.Column(col.name, col.type, primary_key=True) for col in self.pk_columns()]
@@ -301,10 +301,13 @@ class StoreBase:
301
301
  )
302
302
  log_explain(_logger, update_stmt, conn)
303
303
  conn.execute(update_stmt)
304
-
305
304
  finally:
306
- tmp_tbl.drop(bind=conn)
307
- self.sa_md.remove(tmp_tbl)
305
+
306
+ def remove_tmp_tbl() -> None:
307
+ self.sa_md.remove(tmp_tbl)
308
+ tmp_tbl.drop(bind=conn)
309
+
310
+ run_cleanup(remove_tmp_tbl, raise_error=True)
308
311
  return num_excs
309
312
 
310
313
  def insert_rows(
@@ -0,0 +1,59 @@
1
+ import logging
2
+ import sys
3
+ from typing import Any, Callable, Optional, TypeVar
4
+
5
+ R = TypeVar('R')
6
+
7
+
8
+ def _is_in_exception() -> bool:
9
+ """
10
+ Check if code is currently executing within an exception context.
11
+ """
12
+ current_exception = sys.exc_info()[1]
13
+ return current_exception is not None
14
+
15
+
16
+ def run_cleanup_on_exception(cleanup_func: Callable[..., R], *args: Any, **kwargs: Any) -> Optional[R]:
17
+ """
18
+ Runs cleanup only when running in exception context.
19
+
20
+ The function `run_cleanup_on_exception()` should be used to clean up resources when an operation fails.
21
+ This is typically done using a try, except, and finally block, with the resource cleanup logic placed within
22
+ the except block. However, this pattern may not handle KeyboardInterrupt exceptions.
23
+ To ensure that resources are always cleaned up at least once when an exception or KeyboardInterrupt occurs,
24
+ create an idempotent function for cleaning up resources and pass it to the `run_cleanup_on_exception()` function
25
+ from the finally block.
26
+ """
27
+ if _is_in_exception():
28
+ return run_cleanup(cleanup_func, *args, raise_error=False, **kwargs)
29
+ return None
30
+
31
+
32
+ def run_cleanup(cleanup_func: Callable[..., R], *args: Any, raise_error: bool = True, **kwargs: Any) -> Optional[R]:
33
+ """
34
+ Runs a cleanup function. If interrupted, retry cleanup.
35
+ The `run_cleanup()` function ensures that the `cleanup_func()` function executes at least once.
36
+ If the `cleanup_func()` is interrupted during execution, it will be retried.
37
+
38
+ Args:
39
+ cleanup_func: an idempotent function
40
+ raise_error: raise an exception if an error occurs during cleanup.
41
+ """
42
+ try:
43
+ logging.debug(f'Running cleanup function: {cleanup_func.__name__!r}')
44
+ return cleanup_func(*args, **kwargs)
45
+ except KeyboardInterrupt as interrupt:
46
+ # Save original exception and re-attempt cleanup
47
+ original_exception = interrupt
48
+ logging.debug(f'Cleanup {cleanup_func.__name__!r} interrupted, retrying')
49
+ try:
50
+ return cleanup_func(*args, **kwargs)
51
+ except Exception as e:
52
+ # Suppress this exception
53
+ logging.error(f'Cleanup {cleanup_func.__name__!r} failed with exception {e}')
54
+ raise KeyboardInterrupt from original_exception
55
+ except Exception as e:
56
+ logging.error(f'Cleanup {cleanup_func.__name__!r} failed with exception {e}')
57
+ if raise_error:
58
+ raise e
59
+ return None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pixeltable
3
- Version: 0.3.11
3
+ Version: 0.3.12
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
@@ -1,19 +1,19 @@
1
- pixeltable/__init__.py,sha256=hSQqCuVinIpYLIBuOOh2cV-pP8-1buk0zT9xCtqxaSA,1658
2
- pixeltable/__version__.py,sha256=nKy1w-9YfBgJ1lnl8j1yahk-Vtoogyun-3QYELntNCM,114
1
+ pixeltable/__init__.py,sha256=Z0MfZlFI062slLkXfKM-LBwnU5mzDXL1rH590cZGZmo,1673
2
+ pixeltable/__version__.py,sha256=8uFR7F1FvhAJZVB_O7-LoYs_kNA6FS4Knmjr_gvBaUE,114
3
3
  pixeltable/catalog/__init__.py,sha256=rQmjveID4bk6NI4Ql09lGsZ0K0HVE2l1yqKAveipHzc,558
4
- pixeltable/catalog/catalog.py,sha256=5b8rad0ZXInofr75AP-7Al53DOPx3E1Sy5OKu_YrrkQ,35425
4
+ pixeltable/catalog/catalog.py,sha256=7aS-p3Y1ArYqi2gvD57bF-VC0eGvOkeZ4HCKFUNQK7Y,48756
5
5
  pixeltable/catalog/column.py,sha256=i_KJVRvjR9Dh4tPrdf9Fg7IBGcKLYiOJKngSVBLgMCA,10800
6
6
  pixeltable/catalog/dir.py,sha256=HFemOf67Nfw13EOpQsR_UgzP2L1w4LDfw2009DrSK0Y,2063
7
- pixeltable/catalog/globals.py,sha256=FwMnw6TVcuTLklrDr6MUmw3Sxg30_v5i3MAWf_VFflM,3910
8
- pixeltable/catalog/insertable_table.py,sha256=FtDCCwr3O9cnx-nR24uNos2rTe9bETUZdfKYtjKrQ1w,8553
7
+ pixeltable/catalog/globals.py,sha256=7fNUs67D18PZ1ZajcGz7KQOV6tuXEcYLSrePzgmDkRw,4036
8
+ pixeltable/catalog/insertable_table.py,sha256=Ote3E1kcOQ5SJOKrwRSqiKsjEujht9Vi_KO3dwd_0k8,8582
9
9
  pixeltable/catalog/named_function.py,sha256=vZ-j7P4HugWh9OmUzBMwyRYvO3tQn9jWyJz_1stPavU,1210
10
- pixeltable/catalog/path.py,sha256=LUQ1vmSbUaZ66yBn8H4SLV6UJLx96EgHAvUKjqxazrQ,2211
10
+ pixeltable/catalog/path.py,sha256=gk8TIlO_7Jpji5mAN0dUNvHmvU0uneTHeB_qCTWnszQ,2529
11
11
  pixeltable/catalog/schema_object.py,sha256=6OxJTfT1NOivL1sbg8opf4DTGvGCLqqkuuS4Xo8ESJU,1806
12
- pixeltable/catalog/table.py,sha256=6j_oWxtDtNIJ1NnuJ9ZbqJ6bH7t8J_ahcmjDCDRnYjs,65353
13
- pixeltable/catalog/table_version.py,sha256=5L80BWRbCn_mzKlLat7rEVqIvFTkBb2xebQB6RelU6k,59656
12
+ pixeltable/catalog/table.py,sha256=pXKfC1fgLV8qdWK8zSRJSsr3-OQxPKZAPaO_rgO7wEc,65442
13
+ pixeltable/catalog/table_version.py,sha256=iVZnJ0CfNk4i2oiGppb2ZqShStG509_nFkyrR3jOLwo,61490
14
14
  pixeltable/catalog/table_version_handle.py,sha256=LYJFTdRssPu4uOBPbP93wKqXygJXr3Gwdc9wHzzZRag,1654
15
15
  pixeltable/catalog/table_version_path.py,sha256=_g9knGenpMOlhaK8DZa8iLz5CorsMcbnFqTLnvaUkYM,6653
16
- pixeltable/catalog/view.py,sha256=1naZXwuGO1XzOiqxRI-NhJA_jZQ6z2G5pf__qA6Pm6E,11683
16
+ pixeltable/catalog/view.py,sha256=iwqj9E-AxPK52XqyCjltbEU14dnImhFbvWpRoysjXr0,11579
17
17
  pixeltable/config.py,sha256=gnRI4G9GE7mQJDcMcn8JsEzYk8oKVfHB-BwoLRWnRDo,3971
18
18
  pixeltable/dataframe.py,sha256=4RnQtRVJSWNzpJPQued9lyXSU3FW1Zeul502WCOxDQk,49585
19
19
  pixeltable/env.py,sha256=uQ8LZG-KU96Jhgs0wAUOn0rrj1ouAeliavnJPgvDx_Q,36250
@@ -33,7 +33,7 @@ pixeltable/exec/expr_eval/row_buffer.py,sha256=YY0thdlMNNReEOTyPp36xKPeMeXSZ0VrI
33
33
  pixeltable/exec/expr_eval/schedulers.py,sha256=tAvCQKa1q0x7y7cdnGcTGbeku8QcoKH1GkgSm8ktOnM,17000
34
34
  pixeltable/exec/in_memory_data_node.py,sha256=csw_4qyOKsvqgIiqX6IMDw6wi2pqnHwLgoE_77j7Pck,3594
35
35
  pixeltable/exec/row_update_node.py,sha256=zU0eSyn81-vRrjAMOadRqU8luTshnPUtIbS7npyLBKY,2798
36
- pixeltable/exec/sql_node.py,sha256=FNzXxPhtQ7iQoht4QeXp5sAFZorRkVb9ttkpkOPsBbY,19871
36
+ pixeltable/exec/sql_node.py,sha256=4UmnUP50sCNRZ1eCtRauoKdosPL7tlJqnqXZI_w1u90,19752
37
37
  pixeltable/exprs/__init__.py,sha256=AxSMjKNavCT9F6vBaNR-nwX2iupAI5hbMb5hEj65Tfk,1096
38
38
  pixeltable/exprs/arithmetic_expr.py,sha256=sZPao0qdFWbrDx0eiAVxw1wGHJXZ5ZoCpQaScysBldE,7333
39
39
  pixeltable/exprs/array_slice.py,sha256=8Zv0E2RghdJi1Mbk0kKtOz2ccGQuXwLLb6R9v1jk7hA,2180
@@ -51,7 +51,7 @@ pixeltable/exprs/in_predicate.py,sha256=u98JmBX9XsglKe5uCy1NUMnyi3wioBri_tue2vI9
51
51
  pixeltable/exprs/inline_expr.py,sha256=XYVKKXZN9BtHN5qlvZna-mgdOlot6WcmPu5usRBYei0,7972
52
52
  pixeltable/exprs/is_null.py,sha256=NfA_485hfT69pWyY6u8BhykDUkz5k91AH93azGu6lCg,1087
53
53
  pixeltable/exprs/json_mapper.py,sha256=bJSB39sZgpN9KS0RReDnUhTCwg-4Y4cgXXaFNy3o3wU,7035
54
- pixeltable/exprs/json_path.py,sha256=RFSS1zgNRY2Qen0TPxaPY1ae9ehkZ2XuTsnhdVlpsic,7224
54
+ pixeltable/exprs/json_path.py,sha256=sFuDjfz8_rlea4TKd68CS4pQTUiLDi68YwsgcQRHffI,7162
55
55
  pixeltable/exprs/literal.py,sha256=j4Rq5dGPbf7E3E4fqFgHtq0roiRtiy-9J03FaamEEVw,4315
56
56
  pixeltable/exprs/method_ref.py,sha256=NNhJTGo7luZLh8EJdFIZAax9LiiqqDCEK1AwPmHip0w,2642
57
57
  pixeltable/exprs/object_ref.py,sha256=idYFcT27jv0BjtJT3paL37xDrZZc35_3eCJyQOIqdZU,1999
@@ -66,16 +66,16 @@ pixeltable/ext/__init__.py,sha256=UgDXWzGWiQIrwOuEvWTePLBcR2kecllPAE7gp-42Awg,45
66
66
  pixeltable/ext/functions/__init__.py,sha256=Ox3kUHn5IslVEmEKsjrHfkHDrUkmLl9RCO2YkrPJkgc,193
67
67
  pixeltable/ext/functions/whisperx.py,sha256=qda6kFQSvZTY2asfrYPwHb1cvSa03LbhJ-Wf9b7qPhw,2355
68
68
  pixeltable/ext/functions/yolox.py,sha256=dX22nMb-0n2hZi7WhZ1Y4LIpFk5loyeXXuSUcc2Fgrg,3724
69
- pixeltable/func/__init__.py,sha256=HS9WQcHPbp9fvaWdeuh0VEk1UrdtbAFvfAm8lRMWjSI,494
70
- pixeltable/func/aggregate_function.py,sha256=eeEJ1O604G4lMbIPndpuvnCyfbaRU46jn-gvllosFQ4,13267
71
- pixeltable/func/callable_function.py,sha256=Wre4p8RelolvpukwbetzW_PONjL0gqzUPKBsu1zjJeM,9281
72
- pixeltable/func/expr_template_function.py,sha256=ncbSfDdHEKHHhPA-PXGu97HBFmkLQB0Th_NoKjx84ZY,5946
73
- pixeltable/func/function.py,sha256=cbHufGcWxq_oWaHXAnXSXf7KdT8zAuWLNv-XD8DOVg4,23155
69
+ pixeltable/func/__init__.py,sha256=2BtyvXvFrLF0S5Qnmtg9S7dDSEVoBh5GDX6XFC25d7o,509
70
+ pixeltable/func/aggregate_function.py,sha256=5_MgqHAlMaacX2sPIHv_auTvYXtqR5MIZy_WqYQSdho,13264
71
+ pixeltable/func/callable_function.py,sha256=g_pA-g631YcFGLix9PpHYfgjOeS2qF0Csm1VxX8fah0,9278
72
+ pixeltable/func/expr_template_function.py,sha256=wEidKrOBTZkA3U1PAtG6-6RlDFiiRJszIG4zNOuPcNY,5940
73
+ pixeltable/func/function.py,sha256=1xyvSJ_OC4nYlQmh3Og9h2EK68OVFR2ZQEKChmslTcg,23137
74
74
  pixeltable/func/function_registry.py,sha256=7AQ1bdF2DJbTRn9xx6s5cC_VHtCBXGt_GyJJEjJHcMw,12308
75
75
  pixeltable/func/globals.py,sha256=5Wo4GPxYgHRRk5nvV0h_lAthKSalxKvj5n1p-uMPR0U,1501
76
- pixeltable/func/query_template_function.py,sha256=XFTbxfLkzLySxfOYnmr1B5pthj3kE0zFLlHrdorZdns,4341
76
+ pixeltable/func/query_template_function.py,sha256=QN_HGyBErDwdwpsI63caohsjo9usoN6WTEERG6NDtP4,7913
77
77
  pixeltable/func/signature.py,sha256=0PI6xdhLgwy9-GMkzkm7GlsBnsNMiS9aoNI9LWXwvN0,13700
78
- pixeltable/func/tools.py,sha256=e-qUSkvRJu5blUJ1C-5BK8qG6GWQ8ESvhehHQgQ5UkQ,5724
78
+ pixeltable/func/tools.py,sha256=DIfkOEj9Bp797Ew014_4YJePoUW40fQ6mvbCeg0FBR0,5721
79
79
  pixeltable/func/udf.py,sha256=anBoJUAjUa46_SbZuIVLRpRCmW_D9Ce1UeV0NyeWR3Y,13213
80
80
  pixeltable/functions/__init__.py,sha256=egLhhTusyiP9GkwImx8wT4nwO-eTxkmSPJ7NEn8TFmw,555
81
81
  pixeltable/functions/anthropic.py,sha256=-NYawpiNJkYrZLvF1MA6JxlQBId0sNTNKnuw-tF9XKY,9324
@@ -100,7 +100,7 @@ pixeltable/functions/util.py,sha256=lVya13gcao8T34OGX7zy1cglQPNwaBbSBw57bVPyHNs,
100
100
  pixeltable/functions/video.py,sha256=rrKYGCEm-oJVQnjiNbEjDykusAtaQDLrYFNqv8Twwcw,6948
101
101
  pixeltable/functions/vision.py,sha256=_a0wY3akkVhWnnxlq__1VzSLylytlNadpNOOPOwSfLk,15393
102
102
  pixeltable/functions/whisper.py,sha256=c9E6trhc2UcShVaGaEBCUEpArke1ql3MV5We0qSgmuU,2960
103
- pixeltable/globals.py,sha256=SOEBBXfb3YEHY7fiIjp3a0LTx_vAmpeUXUigMKedsTQ,30897
103
+ pixeltable/globals.py,sha256=56Mxnrw9Jt4yq8ZzYT8Wyvki-MtOqK-st1FTfEfH7qE,31023
104
104
  pixeltable/index/__init__.py,sha256=97aFuxiP_oz1ldn5iq8IWApkOV8XG6ZIBW5-9rkS0vM,122
105
105
  pixeltable/index/base.py,sha256=jrE2Sack14_o_oFWkQf_qdDCSQ85SCZLcJX4GhU_JaY,1527
106
106
  pixeltable/index/btree.py,sha256=m4eUk8jVG5h2VW_IcsmWG4GN-FFk0uFHyDF6FSw_gbM,2299
@@ -123,7 +123,7 @@ pixeltable/iterators/document.py,sha256=wJYSnzusJFaxipv5y0uQw-surN9fFz0Aq-s7w_l_
123
123
  pixeltable/iterators/image.py,sha256=nWm-03CxNvHRdTr8U6PvWEnEiquqIQNG5rB-3Y44Mm4,3440
124
124
  pixeltable/iterators/string.py,sha256=URj5edWp-CsorjN_8nnfWGvtIFs_Zh4VPm6htlJbFkU,1257
125
125
  pixeltable/iterators/video.py,sha256=L5S1YPmT_zM11vW9fK6d5nQpUvHVewQWmfDmy4BD45E,9134
126
- pixeltable/metadata/__init__.py,sha256=37m9C-NzUdQGXKucCPLoKOhwOk_1ENSPAdmxEsntgX8,2607
126
+ pixeltable/metadata/__init__.py,sha256=5l_hdB3w43VQAS6AibUBHeUsn3IdCyIcsMENEPS1AuY,2607
127
127
  pixeltable/metadata/converters/convert_10.py,sha256=myYIo1DyccnsQUxDKG6mafnU5ge_EhZpHg_pesKBoK4,708
128
128
  pixeltable/metadata/converters/convert_12.py,sha256=Ci-qyZW1gqci-8wnjeOB5afdq7KTuN-hVSV9OqSPx8g,162
129
129
  pixeltable/metadata/converters/convert_13.py,sha256=yFR6lD3pOrZ46ZQBFKYvxiIYa7rRxh46Bsq7yiCBNak,1356
@@ -144,15 +144,18 @@ pixeltable/metadata/converters/convert_27.py,sha256=1P7DSAXPwHqkXvNxFqjIOcdI8dls
144
144
  pixeltable/metadata/converters/convert_28.py,sha256=v2CqpXAbCTQ-3gbn_ZtSl0fXueK1Q7VDECbIc7Ci1VQ,694
145
145
  pixeltable/metadata/converters/convert_29.py,sha256=aBqZeXiYbtcAX3MiuEgqPkfzd8Hu8oNYjO-lJafmfOg,4912
146
146
  pixeltable/metadata/converters/convert_30.py,sha256=DKCD6ZMgRU2Cu7eonB1kYEnYCKI40m2XIjTiOyFsCyA,1450
147
+ pixeltable/metadata/converters/convert_31.py,sha256=pFjZGpuFlGRPxKYYidiSCIMNaEEXVuLTnELi3y_pSQo,424
148
+ pixeltable/metadata/converters/convert_32.py,sha256=YENfuQ_mqhnZWrvHJffaGEqd1IwS2RjTGPkEvOs5sUs,406
149
+ pixeltable/metadata/converters/convert_33.py,sha256=ZZV3FTyyouBM1eNymXxfHV-Oqmgu2s0KNP6AG3zc5eM,574
147
150
  pixeltable/metadata/converters/util.py,sha256=qnhrwUS7nSczCdrMjKG7v3lRxRKh9o19epCtP8HTpsY,7729
148
- pixeltable/metadata/notes.py,sha256=zqFAbQi56oypFk34WeOaQOSlJxoVj8MHonGL9SPKPE4,1084
149
- pixeltable/metadata/schema.py,sha256=3x2ldgcV5_XdPk9Awn3JbS7meqJ4_-BiDtD1-XAYCHI,10234
150
- pixeltable/plan.py,sha256=ExvFuwqOdOEcl4UeWFlKS2rWn8eVGhvJPuNx2o4vgm0,43392
151
+ pixeltable/metadata/notes.py,sha256=6S6QEBH15QQwR7DcE0y27LrxYe_GI_tC-h7gk5RnrcE,1269
152
+ pixeltable/metadata/schema.py,sha256=EKmx29vfQo3eGD2uCJW_lPalPialSb2oUSBGTyewduE,11261
153
+ pixeltable/plan.py,sha256=s2wS4DIBzr19QlGCJNdPVZ_Od1FVJpTGEb7opNbHtHM,43260
151
154
  pixeltable/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
152
155
  pixeltable/share/__init__.py,sha256=zTJtLn0F7-5DgSIpxUvFQPO2LP7AOw9xjEaD30RH62U,58
153
- pixeltable/share/packager.py,sha256=1jXKF7bCtN4cZ57Kxk4Z2tonD2ML-A-xHhCIU68zg8w,11838
154
- pixeltable/share/publish.py,sha256=0aRgiX2c-RuwyAuekbQXza-lsKIgtlpnM5ZbYNCoYbc,3807
155
- pixeltable/store.py,sha256=ZkXaeHOplT4ssg8_6Lymsb3bJ9vIWlcKSRkuWznxHEs,22501
156
+ pixeltable/share/packager.py,sha256=mDVfOkkkc2rWEfLX35vKBuUkYQenkTKT6MhkqqXNj6U,11110
157
+ pixeltable/share/publish.py,sha256=pnldL8_k71Ta9Mn_KDothhizB83Nm8Q3IsESmr9gg3k,4643
158
+ pixeltable/store.py,sha256=G1kCi4rEFg__driaB0fGRQ8dip2YPO83bZtwXqhwoOg,22668
156
159
  pixeltable/type_system.py,sha256=xGRgz6tQzmBDZ3Lvzq7vTfD1WDJg-pa7UUMw1vv0PeE,52378
157
160
  pixeltable/utils/__init__.py,sha256=Pwgu-Sg1XkxzdCZ4ZhWP77UgLP3tnQsyCKaUJLF4ajo,1741
158
161
  pixeltable/utils/arrow.py,sha256=2R0rhin1-dN0O5aL_s8LZYE7Or4mdf5LCRbe2OOsz2A,6292
@@ -163,6 +166,7 @@ pixeltable/utils/coroutine.py,sha256=IPUqBpwHkDNaioMde7Km3LU8s54SGXVOtRJpYPkm1gE
163
166
  pixeltable/utils/dbms.py,sha256=qm6O6leJJT0c5323cZnJTW5W_4rvQVfD4YFMbuw1mpM,2021
164
167
  pixeltable/utils/description_helper.py,sha256=acibNm36wkZG7h6k8gjcypTD_PVV2SL7YgX6cPYP1i8,3743
165
168
  pixeltable/utils/documents.py,sha256=x3UHU7eykibyA3eVkSrCK1CQoaid228vp96WUEESssU,3105
169
+ pixeltable/utils/exception_handler.py,sha256=yrTAtUJEOhldps_k6aRLEf5yQ8gYGhl9c6ewYNC4Qfc,2476
166
170
  pixeltable/utils/filecache.py,sha256=8RZZiEkD4awZpR-mn7OhoZPc6_JlPUNSBnMU8BcEAv4,10864
167
171
  pixeltable/utils/formatter.py,sha256=_pYQOhBh2dZBeCTUKuWaIzm7JRWeMepMZwSd5KTv-tw,9220
168
172
  pixeltable/utils/http_server.py,sha256=B5iQ1s_VuwsVC7pUm1joGjLZqaluV8_RfFiU8V1FuG8,2453
@@ -172,8 +176,8 @@ pixeltable/utils/pytorch.py,sha256=rrqXn6KVXmABEPGLjjq3qYINfCCv9SbpfPFmSx9KyGQ,3
172
176
  pixeltable/utils/s3.py,sha256=pxip2MlCqd2Qon2dzJXzfxvwtZyc-BAsjAnLL4J_OXY,587
173
177
  pixeltable/utils/sql.py,sha256=Sa4Lh-VGe8GToU5W7DRiWf2lMl9B6saPqemiT0ZdHEc,806
174
178
  pixeltable/utils/transactional_directory.py,sha256=OFKmu90oP7KwBAljwjnzP_w8euGdAXob3y4Nx9SCNHA,1357
175
- pixeltable-0.3.11.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
176
- pixeltable-0.3.11.dist-info/METADATA,sha256=HLcfKQsJZ8zJa4w0whkhCRgb1GMSkVq2gvNH0HZ3IM4,20629
177
- pixeltable-0.3.11.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
178
- pixeltable-0.3.11.dist-info/entry_points.txt,sha256=ToOd-pRgG7AitEBgYoBCRRB4-KVDQ0pj_9T4a1LgwA4,97
179
- pixeltable-0.3.11.dist-info/RECORD,,
179
+ pixeltable-0.3.12.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
180
+ pixeltable-0.3.12.dist-info/METADATA,sha256=x0ONNIBctMVl4Ir9bnLJxwSYs-a9gCdNzYldkYGu4vU,20629
181
+ pixeltable-0.3.12.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
182
+ pixeltable-0.3.12.dist-info/entry_points.txt,sha256=ToOd-pRgG7AitEBgYoBCRRB4-KVDQ0pj_9T4a1LgwA4,97
183
+ pixeltable-0.3.12.dist-info/RECORD,,