pixeltable 0.4.10__py3-none-any.whl → 0.4.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.

@@ -1478,12 +1478,17 @@ class Table(SchemaObject):
1478
1478
  return result
1479
1479
 
1480
1480
  def recompute_columns(
1481
- self, *columns: str | ColumnRef, errors_only: bool = False, cascade: bool = True
1481
+ self,
1482
+ *columns: str | ColumnRef,
1483
+ where: 'exprs.Expr' | None = None,
1484
+ errors_only: bool = False,
1485
+ cascade: bool = True,
1482
1486
  ) -> UpdateStatus:
1483
1487
  """Recompute the values in one or more computed columns of this table.
1484
1488
 
1485
1489
  Args:
1486
1490
  columns: The names or references of the computed columns to recompute.
1491
+ where: A predicate to filter rows to recompute.
1487
1492
  errors_only: If True, only run the recomputation for rows that have errors in the column (ie, the column's
1488
1493
  `errortype` property indicates that an error occurred). Only allowed for recomputing a single column.
1489
1494
  cascade: if True, also update all computed columns that transitively depend on the recomputed columns.
@@ -1499,6 +1504,10 @@ class Table(SchemaObject):
1499
1504
 
1500
1505
  >>> tbl.recompute_columns(tbl.c1, tbl.c2, cascade=False)
1501
1506
 
1507
+ Recompute column `c1` and its dependents, but only for rows with `c2` == 0:
1508
+
1509
+ >>> tbl.recompute_columns('c1', where=tbl.c2 == 0)
1510
+
1502
1511
  Recompute column `c1` and its dependents, but only for rows that have errors in it:
1503
1512
 
1504
1513
  >>> tbl.recompute_columns('c1', errors_only=True)
@@ -1535,7 +1544,12 @@ class Table(SchemaObject):
1535
1544
  raise excs.Error(f'Cannot recompute column of a base: {col_name!r}')
1536
1545
  col_names.append(col_name)
1537
1546
 
1538
- result = self._tbl_version.get().recompute_columns(col_names, errors_only=errors_only, cascade=cascade)
1547
+ if where is not None and not where.is_bound_by([self._tbl_version_path]):
1548
+ raise excs.Error(f"'where' ({where}) not bound by {self._display_str()}")
1549
+
1550
+ result = self._tbl_version.get().recompute_columns(
1551
+ col_names, where=where, errors_only=errors_only, cascade=cascade
1552
+ )
1539
1553
  FileCache.get().emit_eviction_warnings()
1540
1554
  return result
1541
1555
 
@@ -1065,21 +1065,28 @@ class TableVersion:
1065
1065
 
1066
1066
  return update_targets
1067
1067
 
1068
- def recompute_columns(self, col_names: list[str], errors_only: bool = False, cascade: bool = True) -> UpdateStatus:
1068
+ def recompute_columns(
1069
+ self, col_names: list[str], where: exprs.Expr | None = None, errors_only: bool = False, cascade: bool = True
1070
+ ) -> UpdateStatus:
1069
1071
  assert self.is_mutable
1070
1072
  assert all(name in self.cols_by_name for name in col_names)
1071
1073
  assert len(col_names) > 0
1072
1074
  assert len(col_names) == 1 or not errors_only
1073
1075
 
1076
+ from pixeltable.exprs import CompoundPredicate
1074
1077
  from pixeltable.plan import Planner
1075
1078
 
1076
1079
  target_columns = [self.cols_by_name[name] for name in col_names]
1077
1080
  where_clause: Optional[exprs.Expr] = None
1081
+ if where is not None:
1082
+ self._validate_where_clause(where, error_prefix="'where' argument")
1083
+ where_clause = where
1078
1084
  if errors_only:
1079
- where_clause = (
1085
+ errortype_pred = (
1080
1086
  exprs.ColumnPropertyRef(exprs.ColumnRef(target_columns[0]), exprs.ColumnPropertyRef.Property.ERRORTYPE)
1081
1087
  != None
1082
1088
  )
1089
+ where_clause = CompoundPredicate.make_conjunction([where_clause, errortype_pred])
1083
1090
  plan, updated_cols, recomputed_cols = Planner.create_update_plan(
1084
1091
  self.path, update_targets={}, recompute_targets=target_columns, where_clause=where_clause, cascade=cascade
1085
1092
  )
@@ -1142,40 +1149,30 @@ class TableVersion:
1142
1149
  self._write_md(new_version=True, new_schema_version=False)
1143
1150
  return result
1144
1151
 
1145
- def delete(self, where: Optional[exprs.Expr] = None) -> UpdateStatus:
1146
- """Delete rows in this table.
1147
- Args:
1148
- where: a predicate to filter rows to delete.
1149
-
1150
- Returns:
1151
- UpdateStatus: an object containing the number of deleted rows and other statistics.
1152
- """
1152
+ def _validate_where_clause(self, pred: exprs.Expr, error_prefix: str) -> None:
1153
+ """Validates that pred can be expressed as a SQL Where clause"""
1153
1154
  assert self.is_insertable
1154
1155
  from pixeltable.exprs import Expr
1155
1156
  from pixeltable.plan import Planner
1156
1157
 
1157
- sql_where_clause: Optional[Expr] = None
1158
- if where is not None:
1159
- if not isinstance(where, Expr):
1160
- raise excs.Error(f"'where' argument must be a predicate, got {type(where)}")
1161
- analysis_info = Planner.analyze(self.path, where)
1162
- # for now we require that the updated rows can be identified via SQL, rather than via a Python filter
1163
- if analysis_info.filter is not None:
1164
- raise excs.Error(f'Filter {analysis_info.filter} not expressible in SQL')
1165
- sql_where_clause = analysis_info.sql_where_clause
1158
+ if not isinstance(pred, Expr):
1159
+ raise excs.Error(f'{error_prefix} must be a predicate, got {type(pred)}')
1160
+ analysis_info = Planner.analyze(self.path, pred)
1161
+ # for now we require that the updated rows can be identified via SQL, rather than via a Python filter
1162
+ if analysis_info.filter is not None:
1163
+ raise excs.Error(f'Filter {analysis_info.filter} not expressible in SQL')
1166
1164
 
1167
- status = self.propagate_delete(sql_where_clause, base_versions=[], timestamp=time.time())
1165
+ def delete(self, where: exprs.Expr | None = None) -> UpdateStatus:
1166
+ assert self.is_insertable
1167
+ if where is not None:
1168
+ self._validate_where_clause(where, error_prefix="'where' argument")
1169
+ status = self.propagate_delete(where, base_versions=[], timestamp=time.time())
1168
1170
  return status
1169
1171
 
1170
1172
  def propagate_delete(
1171
1173
  self, where: Optional[exprs.Expr], base_versions: list[Optional[int]], timestamp: float
1172
1174
  ) -> UpdateStatus:
1173
- """Delete rows in this table and propagate to views.
1174
- Args:
1175
- where: a predicate to filter rows to delete.
1176
- Returns:
1177
- number of deleted rows
1178
- """
1175
+ """Delete rows in this table and propagate to views"""
1179
1176
  # print(f'calling sql_expr()')
1180
1177
  sql_where_clause = where.sql_expr(exprs.SqlElementCache()) if where is not None else None
1181
1178
  # #print(f'sql_where_clause={str(sql_where_clause) if sql_where_clause is not None else None}')
@@ -323,7 +323,9 @@ class View(Table):
323
323
  else:
324
324
  base_descr = f'{base._path()}:{effective_version}'
325
325
  bases_descrs.append(f'{base_descr!r}')
326
- result.append(f' (of {", ".join(bases_descrs)})')
326
+ if len(bases_descrs) > 0:
327
+ # bases_descrs can be empty in the case of a table-replica
328
+ result.append(f' (of {", ".join(bases_descrs)})')
327
329
 
328
330
  if self._tbl_version_path.tbl_version.get().predicate is not None:
329
331
  result.append(f'\nWhere: {self._tbl_version_path.tbl_version.get().predicate!s}')
pixeltable/dataframe.py CHANGED
@@ -1210,17 +1210,42 @@ class DataFrame:
1210
1210
  Via the above DataFrame person, update the column 'city' to 'Oakland'
1211
1211
  and 'state' to 'CA' in the table t:
1212
1212
 
1213
- >>> df = person.update({'city': 'Oakland', 'state': 'CA'})
1213
+ >>> person.update({'city': 'Oakland', 'state': 'CA'})
1214
1214
 
1215
1215
  Via the above DataFrame person, update the column 'age' to 30 for any
1216
1216
  rows where 'year' is 2014 in the table t:
1217
1217
 
1218
- >>> df = person.where(t.year == 2014).update({'age': 30})
1218
+ >>> person.where(t.year == 2014).update({'age': 30})
1219
1219
  """
1220
1220
  self._validate_mutable('update', False)
1221
1221
  with Catalog.get().begin_xact(tbl=self._first_tbl, for_write=True, lock_mutable_tree=True):
1222
1222
  return self._first_tbl.tbl_version.get().update(value_spec, where=self.where_clause, cascade=cascade)
1223
1223
 
1224
+ def recompute_columns(
1225
+ self, *columns: str | exprs.ColumnRef, errors_only: bool = False, cascade: bool = True
1226
+ ) -> UpdateStatus:
1227
+ """Recompute one or more computed columns of the underlying table of the DataFrame.
1228
+
1229
+ Args:
1230
+ columns: The names or references of the computed columns to recompute.
1231
+ errors_only: If True, only run the recomputation for rows that have errors in the column (ie, the column's
1232
+ `errortype` property indicates that an error occurred). Only allowed for recomputing a single column.
1233
+ cascade: if True, also update all computed columns that transitively depend on the recomputed columns.
1234
+
1235
+ Returns:
1236
+ UpdateStatus: the status of the operation.
1237
+
1238
+ Example:
1239
+ For table `person` with column `age` and computed column `height`, recompute the value of `height` for all
1240
+ rows where `age` is less than 18:
1241
+
1242
+ >>> df = person.where(t.age < 18).recompute_columns(person.height)
1243
+ """
1244
+ self._validate_mutable('recompute_columns', False)
1245
+ with Catalog.get().begin_xact(tbl=self._first_tbl, for_write=True, lock_mutable_tree=True):
1246
+ tbl = Catalog.get().get_table_by_id(self._first_tbl.tbl_id)
1247
+ return tbl.recompute_columns(*columns, where=self.where_clause, errors_only=errors_only, cascade=cascade)
1248
+
1224
1249
  def delete(self) -> UpdateStatus:
1225
1250
  """Delete rows form the underlying table of the DataFrame.
1226
1251
 
@@ -1230,13 +1255,9 @@ class DataFrame:
1230
1255
  UpdateStatus: the status of the delete operation.
1231
1256
 
1232
1257
  Example:
1233
- Given the DataFrame person from a table t with all its columns and rows:
1234
-
1235
- >>> person = t.select()
1236
-
1237
- Via the above DataFrame person, delete all rows from the table t where the column 'age' is less than 18:
1258
+ For a table `person` with column `age`, delete all rows where 'age' is less than 18:
1238
1259
 
1239
- >>> df = person.where(t.age < 18).delete()
1260
+ >>> person.where(t.age < 18).delete()
1240
1261
  """
1241
1262
  self._validate_mutable('delete', False)
1242
1263
  if not self._first_tbl.is_insertable():
pixeltable/env.py CHANGED
@@ -605,12 +605,7 @@ class Env:
605
605
  metadata.upgrade_md(self._sa_engine)
606
606
 
607
607
  @property
608
- def pxt_api_key(self) -> str:
609
- if self._pxt_api_key is None:
610
- raise excs.Error(
611
- 'No API key is configured. Set the PIXELTABLE_API_KEY environment variable, or add an entry to '
612
- 'config.toml as described here:\nhttps://pixeltable.github.io/pixeltable/config/'
613
- )
608
+ def pxt_api_key(self) -> Optional[str]:
614
609
  return self._pxt_api_key
615
610
 
616
611
  def get_client(self, name: str) -> Any:
@@ -36,7 +36,8 @@ class CompoundPredicate(Expr):
36
36
  return f' {self.operator} '.join([f'({e})' for e in self.components])
37
37
 
38
38
  @classmethod
39
- def make_conjunction(cls, operands: list[Expr]) -> Optional[Expr]:
39
+ def make_conjunction(cls, operands: list[Expr | None]) -> Expr | None:
40
+ operands = [e for e in operands if e is not None]
40
41
  if len(operands) == 0:
41
42
  return None
42
43
  if len(operands) == 1:
@@ -41,9 +41,9 @@ def _anthropic_client() -> 'anthropic.AsyncAnthropic':
41
41
  def _get_header_info(
42
42
  headers: httpx.Headers,
43
43
  ) -> tuple[
44
- Optional[tuple[int, int, datetime.datetime]],
45
- Optional[tuple[int, int, datetime.datetime]],
46
- Optional[tuple[int, int, datetime.datetime]],
44
+ tuple[int, int, datetime.datetime] | None,
45
+ tuple[int, int, datetime.datetime] | None,
46
+ tuple[int, int, datetime.datetime] | None,
47
47
  ]:
48
48
  """Extract rate limit info from Anthropic API response headers."""
49
49
  requests_limit_str = headers.get('anthropic-ratelimit-requests-limit')
@@ -54,7 +54,9 @@ def _get_header_info(
54
54
  requests_reset = (
55
55
  datetime.datetime.fromisoformat(requests_reset_str.replace('Z', '+00:00')) if requests_reset_str else None
56
56
  )
57
- requests_info = (requests_limit, requests_remaining, requests_reset) if requests_reset else None
57
+ requests_info = (
58
+ (requests_limit, requests_remaining, requests_reset) if requests_reset and requests_remaining else None
59
+ )
58
60
 
59
61
  input_tokens_limit_str = headers.get('anthropic-ratelimit-input-tokens-limit')
60
62
  input_tokens_limit = int(input_tokens_limit_str) if input_tokens_limit_str is not None else None
@@ -66,7 +68,11 @@ def _get_header_info(
66
68
  if input_tokens_reset_str
67
69
  else None
68
70
  )
69
- input_tokens_info = (input_tokens_limit, input_tokens_remaining, input_tokens_reset) if input_tokens_reset else None
71
+ input_tokens_info = (
72
+ (input_tokens_limit, input_tokens_remaining, input_tokens_reset)
73
+ if input_tokens_reset and input_tokens_remaining
74
+ else None
75
+ )
70
76
 
71
77
  output_tokens_limit_str = headers.get('anthropic-ratelimit-output-tokens-limit')
72
78
  output_tokens_limit = int(output_tokens_limit_str) if output_tokens_limit_str is not None else None
@@ -79,9 +85,14 @@ def _get_header_info(
79
85
  else None
80
86
  )
81
87
  output_tokens_info = (
82
- (output_tokens_limit, output_tokens_remaining, output_tokens_reset) if output_tokens_reset else None
88
+ (output_tokens_limit, output_tokens_remaining, output_tokens_reset)
89
+ if output_tokens_reset and output_tokens_remaining
90
+ else None
83
91
  )
84
92
 
93
+ if requests_info is None or input_tokens_info is None or output_tokens_info is None:
94
+ _logger.debug(f'get_header_info(): incomplete rate limit info: {headers}')
95
+
85
96
  return requests_info, input_tokens_info, output_tokens_info
86
97
 
87
98
 
@@ -62,11 +62,11 @@ async def chat_completions(
62
62
  A dictionary containing the response and other metadata.
63
63
 
64
64
  Examples:
65
- Add a computed column that applies the model `llama3-8b-8192`
65
+ Add a computed column that applies the model `llama-3.1-8b-instant`
66
66
  to an existing Pixeltable column `tbl.prompt` of the table `tbl`:
67
67
 
68
68
  >>> messages = [{'role': 'user', 'content': tbl.prompt}]
69
- ... tbl.add_computed_column(response=chat_completions(messages, model='llama3-8b-8192'))
69
+ ... tbl.add_computed_column(response=chat_completions(messages, model='llama-3.1-8b-instant'))
70
70
  """
71
71
  if model_kwargs is None:
72
72
  model_kwargs = {}
@@ -113,7 +113,7 @@ def _parse_header_duration(duration_str: str) -> datetime.timedelta:
113
113
 
114
114
  def _get_header_info(
115
115
  headers: httpx.Headers,
116
- ) -> tuple[Optional[tuple[int, int, datetime.datetime]], Optional[tuple[int, int, datetime.datetime]]]:
116
+ ) -> tuple[tuple[int, int, datetime.datetime] | None, tuple[int, int, datetime.datetime] | None]:
117
117
  now = datetime.datetime.now(tz=datetime.timezone.utc)
118
118
 
119
119
  requests_limit_str = headers.get('x-ratelimit-limit-requests')
@@ -122,7 +122,7 @@ def _get_header_info(
122
122
  requests_remaining = int(requests_remaining_str) if requests_remaining_str is not None else None
123
123
  requests_reset_str = headers.get('x-ratelimit-reset-requests', '5s') # Default to 5 seconds
124
124
  requests_reset_ts = now + _parse_header_duration(requests_reset_str)
125
- requests_info = (requests_limit, requests_remaining, requests_reset_ts)
125
+ requests_info = (requests_limit, requests_remaining, requests_reset_ts) if requests_remaining is not None else None
126
126
 
127
127
  tokens_limit_str = headers.get('x-ratelimit-limit-tokens')
128
128
  tokens_limit = int(tokens_limit_str) if tokens_limit_str is not None else None
@@ -130,7 +130,10 @@ def _get_header_info(
130
130
  tokens_remaining = int(tokens_remaining_str) if tokens_remaining_str is not None else None
131
131
  tokens_reset_str = headers.get('x-ratelimit-reset-tokens', '5s') # Default to 5 seconds
132
132
  tokens_reset_ts = now + _parse_header_duration(tokens_reset_str)
133
- tokens_info = (tokens_limit, tokens_remaining, tokens_reset_ts)
133
+ tokens_info = (tokens_limit, tokens_remaining, tokens_reset_ts) if tokens_remaining is not None else None
134
+
135
+ if requests_info is None or tokens_info is None:
136
+ _logger.debug(f'get_header_info(): incomplete rate limit info: {headers}')
134
137
 
135
138
  return requests_info, tokens_info
136
139
 
pixeltable/globals.py CHANGED
@@ -542,9 +542,14 @@ def drop_table(
542
542
  assert isinstance(table, str)
543
543
  tbl_path = table
544
544
 
545
- path_obj = catalog.Path.parse(tbl_path)
546
- if_not_exists_ = catalog.IfNotExistsParam.validated(if_not_exists, 'if_not_exists')
547
- Catalog.get().drop_table(path_obj, force=force, if_not_exists=if_not_exists_)
545
+ if tbl_path.startswith('pxt://'):
546
+ # Remote table
547
+ share.delete_replica(tbl_path)
548
+ else:
549
+ # Local table
550
+ path_obj = catalog.Path.parse(tbl_path)
551
+ if_not_exists_ = catalog.IfNotExistsParam.validated(if_not_exists, 'if_not_exists')
552
+ Catalog.get().drop_table(path_obj, force=force, if_not_exists=if_not_exists_)
548
553
 
549
554
 
550
555
  def get_dir_contents(dir_path: str = '', recursive: bool = True) -> 'DirContents':
@@ -5,7 +5,7 @@ from .base import ComponentIterator
5
5
  from .document import DocumentSplitter
6
6
  from .image import TileIterator
7
7
  from .string import StringSplitter
8
- from .video import FrameIterator
8
+ from .video import FrameIterator, VideoSplitter
9
9
 
10
10
  __default_dir = {symbol for symbol in dir() if not symbol.startswith('_')}
11
11
  __removed_symbols = {'base', 'document', 'video'}
@@ -1,3 +1,3 @@
1
1
  # ruff: noqa: F401
2
2
 
3
- from .publish import pull_replica, push_replica
3
+ from .publish import delete_replica, pull_replica, push_replica
@@ -27,15 +27,11 @@ PIXELTABLE_API_URL = os.environ.get('PIXELTABLE_API_URL', 'https://internal-api.
27
27
  def push_replica(
28
28
  dest_tbl_uri: str, src_tbl: pxt.Table, bucket: str | None = None, access: Literal['public', 'private'] = 'private'
29
29
  ) -> str:
30
- if not src_tbl._tbl_version_path.is_snapshot():
31
- raise excs.Error('Only snapshots may be published.')
32
-
33
30
  packager = TablePackager(
34
31
  src_tbl, additional_md={'table_uri': dest_tbl_uri, 'bucket_name': bucket, 'is_public': access == 'public'}
35
32
  )
36
33
  request_json = packager.md | {'operation_type': 'publish_snapshot'}
37
- headers_json = {'X-api-key': Env.get().pxt_api_key, 'Content-Type': 'application/json'}
38
- response = requests.post(PIXELTABLE_API_URL, json=request_json, headers=headers_json)
34
+ response = requests.post(PIXELTABLE_API_URL, json=request_json, headers=_api_headers())
39
35
  if response.status_code != 200:
40
36
  raise excs.Error(f'Error publishing snapshot: {response.text}')
41
37
  response_json = response.json()
@@ -70,7 +66,7 @@ def push_replica(
70
66
  'preview_data': packager.md['preview_data'],
71
67
  }
72
68
  # TODO: Use Pydantic for validation
73
- finalize_response = requests.post(PIXELTABLE_API_URL, json=finalize_request_json, headers=headers_json)
69
+ finalize_response = requests.post(PIXELTABLE_API_URL, json=finalize_request_json, headers=_api_headers())
74
70
  if finalize_response.status_code != 200:
75
71
  raise excs.Error(f'Error finalizing snapshot: {finalize_response.text}')
76
72
  finalize_response_json = finalize_response.json()
@@ -112,9 +108,8 @@ def _upload_bundle_to_s3(bundle: Path, parsed_location: urllib.parse.ParseResult
112
108
 
113
109
 
114
110
  def pull_replica(dest_path: str, src_tbl_uri: str) -> pxt.Table:
115
- headers_json = {'X-api-key': Env.get().pxt_api_key, 'Content-Type': 'application/json'}
116
111
  clone_request_json = {'operation_type': 'clone_snapshot', 'table_uri': src_tbl_uri}
117
- response = requests.post(PIXELTABLE_API_URL, json=clone_request_json, headers=headers_json)
112
+ response = requests.post(PIXELTABLE_API_URL, json=clone_request_json, headers=_api_headers())
118
113
  if response.status_code != 200:
119
114
  raise excs.Error(f'Error cloning snapshot: {response.text}')
120
115
  response_json = response.json()
@@ -268,11 +263,18 @@ def _download_from_presigned_url(
268
263
  # TODO: This will be replaced by drop_table with cloud table uri
269
264
  def delete_replica(dest_path: str) -> None:
270
265
  """Delete cloud replica"""
271
- headers_json = {'X-api-key': Env.get().pxt_api_key, 'Content-Type': 'application/json'}
272
266
  delete_request_json = {'operation_type': 'delete_snapshot', 'table_uri': dest_path}
273
- response = requests.post(PIXELTABLE_API_URL, json=delete_request_json, headers=headers_json)
267
+ response = requests.post(PIXELTABLE_API_URL, json=delete_request_json, headers=_api_headers())
274
268
  if response.status_code != 200:
275
269
  raise excs.Error(f'Error deleting replica: {response.text}')
276
270
  response_json = response.json()
277
271
  if not isinstance(response_json, dict) or 'table_uri' not in response_json:
278
272
  raise excs.Error(f'Error deleting replica: unexpected response from server.\n{response_json}')
273
+
274
+
275
+ def _api_headers() -> dict[str, str]:
276
+ headers = {'Content-Type': 'application/json'}
277
+ api_key = Env.get().pxt_api_key
278
+ if api_key is not None:
279
+ headers['X-api-key'] = api_key
280
+ return headers
@@ -189,6 +189,12 @@ class MediaStore:
189
189
  result.sort(key=lambda e: e[3], reverse=True)
190
190
  return result
191
191
 
192
+ def clear(self) -> None:
193
+ """Clear all files from the media store."""
194
+ assert self.__base_dir.exists()
195
+ shutil.rmtree(self.__base_dir)
196
+ self.__base_dir.mkdir()
197
+
192
198
 
193
199
  class TempStore:
194
200
  """
@@ -235,3 +241,8 @@ class TempStore:
235
241
  if tbl_id is not None:
236
242
  return MediaStore(cls._tmp_dir())._prepare_media_path_raw(tbl_id, 0, 0, extension)
237
243
  return cls._tmp_dir() / f'{uuid.uuid4()}{extension}'
244
+
245
+ @classmethod
246
+ def clear(cls) -> None:
247
+ """Clear all files from the temporary store."""
248
+ MediaStore(cls._tmp_dir()).clear()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pixeltable
3
- Version: 0.4.10
3
+ Version: 0.4.12
4
4
  Summary: AI Data Infrastructure: Declarative, Multimodal, and Incremental
5
5
  Project-URL: homepage, https://pixeltable.com/
6
6
  Project-URL: repository, https://github.com/pixeltable/pixeltable
@@ -1,10 +1,10 @@
1
1
  pixeltable/__init__.py,sha256=wJ_4oQdkBAaaVKM8XiZKKSsWPnoemZxh34o6_5vDcxk,1562
2
2
  pixeltable/__version__.py,sha256=LnMIuAxx6nAQDMev_jnZyUdgsaiE3F8lulfXQBRl9qQ,112
3
3
  pixeltable/config.py,sha256=-aoSVF0Aak83IC-u-XANw3if76TDq5VnnWNWoFDR5Hc,8390
4
- pixeltable/dataframe.py,sha256=I6iEJGD4pivUN-cPVFq_rcniZN7C55xpr37sMJ2BIdE,62986
5
- pixeltable/env.py,sha256=vmqDgsfonYLYubsR1N4n5H7aSo4MXtlnBN1Z8xFOeFI,44443
4
+ pixeltable/dataframe.py,sha256=XbrzPjnPgZKJ5lVgPO71cK-nRHCpqGCGWFc52kUO8_E,64213
5
+ pixeltable/env.py,sha256=FlE7s649xBiE5WSs65WwQ4bKbPjMYQaF0Z0HeuEuCs4,44160
6
6
  pixeltable/exceptions.py,sha256=Gm8d3TL2iiv6Pj2DLd29wp_j41qNBhxXL9iTQnL4Nk4,1116
7
- pixeltable/globals.py,sha256=8NijkEmtjY5me6J8zF4G-t1v5_z4q7btOK2yjUREUak,39118
7
+ pixeltable/globals.py,sha256=nR6XJKFlsb12oo_wOWAoAMlnPbHY7FhM3dgEKoM9iSM,39262
8
8
  pixeltable/plan.py,sha256=4yAe7ExAqaSvkFxwK7LPH_HpmoumwqoLeOo7czJ8CyQ,48001
9
9
  pixeltable/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  pixeltable/store.py,sha256=CneWUmgN-EwaPYLcizlAxONC7WYwMr8SNpSFeNBBmOA,22885
@@ -18,13 +18,13 @@ pixeltable/catalog/insertable_table.py,sha256=VUuJ8z7OtMqgy_LMzkn1KzeLXdR-9poTtt
18
18
  pixeltable/catalog/named_function.py,sha256=vZ-j7P4HugWh9OmUzBMwyRYvO3tQn9jWyJz_1stPavU,1210
19
19
  pixeltable/catalog/path.py,sha256=O3FfxrvyX2crijBhp_2k4-3mG3BFxwba-tlPB74QtJQ,3780
20
20
  pixeltable/catalog/schema_object.py,sha256=rQ6-3rzqnOHyEEHi97kai2S7BO3D9AkH7rirnfbGc14,1785
21
- pixeltable/catalog/table.py,sha256=NLo8mcM8SKM8jC4uzRT5elhrC0XTGunjQYznqrCz3w0,81315
22
- pixeltable/catalog/table_version.py,sha256=jTYKzAdQuHBrknQLADBqjLhKwwqeVxmAPosMKsL051Q,64983
21
+ pixeltable/catalog/table.py,sha256=Ug65hRZhzjp3sIUSppA-mXUEWLXgPK22bq22f7WFy0M,81816
22
+ pixeltable/catalog/table_version.py,sha256=SRF2ACp_DcPMLTbc4dbZSgYEfW6-o-UzDOBehecKbb0,65073
23
23
  pixeltable/catalog/table_version_handle.py,sha256=FTPRqcGY-h-POcWyZbd9b8P2D5zIw5OSUvwF_dbyCGo,3608
24
24
  pixeltable/catalog/table_version_path.py,sha256=IaFVDH06_6ZMuBv5eLNCRTlWizpvz95jgAzqp4OVx_o,9713
25
25
  pixeltable/catalog/tbl_ops.py,sha256=Vdcz4Nzvdw09zcQaCEaOr9Uufk2rQHgG0vBvMbQp9R8,1145
26
26
  pixeltable/catalog/update_status.py,sha256=tF3KkDc6kvEQ7Tg3VMj-n774uKi1iLla61wLyeuwDRs,6888
27
- pixeltable/catalog/view.py,sha256=VSBy_8eO76X1ZFtT8T6syjksb-gtcNA-XPMGndRdBy0,15179
27
+ pixeltable/catalog/view.py,sha256=D01t8BNXjAEQiGyG2qCpvflNPsvl4fEk2wPkFpuScCA,15288
28
28
  pixeltable/exec/__init__.py,sha256=hQvj4ra4ubxu94qyuCBTHKsuYGzundkTTluOTIb5Bx8,524
29
29
  pixeltable/exec/aggregation_node.py,sha256=CTMR_p1_TGE-iVUP3jLvlmp5rssjukCKCRv3SjMCOo0,4502
30
30
  pixeltable/exec/cache_prefetch_node.py,sha256=tTFjDKnhWVWA5cVhm44afNp65cyKWIOO3wBU7fd69UM,11905
@@ -47,7 +47,7 @@ pixeltable/exprs/array_slice.py,sha256=C8O0cmGHdc-iVe2FFdW_2jRVR4Gwurzeot6ESEk6R
47
47
  pixeltable/exprs/column_property_ref.py,sha256=rq8VD34fZwAZuN9wIqQEwVay7LTPBKvXXdZPknOJM6M,4422
48
48
  pixeltable/exprs/column_ref.py,sha256=MH83bYsef5UC4vWU71PE-lPiVd8hVw4tT6sjdCCvWNw,15473
49
49
  pixeltable/exprs/comparison.py,sha256=lgaRx000ZaNH10A4hrtsi5XoZKE-CNEONGMi7jxJfcM,5133
50
- pixeltable/exprs/compound_predicate.py,sha256=vJVRVueAmaKnjiHCLWyh8wHgktzzK0DVqbOIQJgTjF8,3801
50
+ pixeltable/exprs/compound_predicate.py,sha256=8nGsBlKaMBe1TT1VrZQ-Khe8rVgB8vukZQSspiHDB7Y,3863
51
51
  pixeltable/exprs/data_row.py,sha256=Pi7oIh3YJ7lh0loeGgIGm9uRhCvOcD8wJNdatHpBMKw,12417
52
52
  pixeltable/exprs/expr.py,sha256=T558PJBeVaHCGgv_TBDUIn-fOZJtSMkz26jGUTpvCVY,35961
53
53
  pixeltable/exprs/expr_dict.py,sha256=2ZeZ0eACx3VrRNEOjipuT5WxOIzjXQ_DSip8NTH0KRo,1584
@@ -82,7 +82,7 @@ pixeltable/func/signature.py,sha256=LdHbdim14Zu7Xt1pMhOCzl6Xn2fq5CQQpwSXmu28umw,
82
82
  pixeltable/func/tools.py,sha256=2_M_u0Jiy5-uToZziB4O54aTuJeaytPmh71q3I2ydNw,6062
83
83
  pixeltable/func/udf.py,sha256=6tKpMt37t3BmXwRyA5fFAd6OM4D5EPEd2KuAr7DQhr0,13231
84
84
  pixeltable/functions/__init__.py,sha256=ZeRB7ksbzjdrvePXtd_mNxyP2RhjvN0ayl5nv7TdWcQ,613
85
- pixeltable/functions/anthropic.py,sha256=2Ja-pryC_3Yd1sXW-pibRuvKjgyfYqOhhl6nBWNOBt0,10504
85
+ pixeltable/functions/anthropic.py,sha256=q1rXr9MWCmnncfZXe8HlU1MVQZdAl4Ft8vdIpR-jgOg,10810
86
86
  pixeltable/functions/audio.py,sha256=S9xSg45Fx5kmB4NxOTSG99_5Kxc8kFfxuawV7qjMeS8,1660
87
87
  pixeltable/functions/bedrock.py,sha256=lTCFHjYunF3minBGWcjXR90yJ8resFjXr4niyKhfxms,4217
88
88
  pixeltable/functions/date.py,sha256=qs1svJ9FVod3OTa5hQNKIuashb6tVhW_2EAEXYGQX74,5308
@@ -90,7 +90,7 @@ pixeltable/functions/deepseek.py,sha256=iw59TKKcw3VqbHMHB2ugtcTPeTVKuHp_3pfkjF6D
90
90
  pixeltable/functions/fireworks.py,sha256=q7eWlYfiWbA0d9r3CB_NAe1fw3q-Z7qsw2gyGJNgWLQ,4786
91
91
  pixeltable/functions/gemini.py,sha256=igtpGBiVekkaWtVE6X04pQ7C9md8nY42W7xU_XuMayE,8924
92
92
  pixeltable/functions/globals.py,sha256=OyPJUJ4S6VWyzxstxIzk3xzYBGIEMwgk1RmSTWTZzdI,5106
93
- pixeltable/functions/groq.py,sha256=FpR_LJpfZfzyhEvoBMMbQpQ-VQSRzBsS9U21qaINwww,3593
93
+ pixeltable/functions/groq.py,sha256=61XbgY4ItASomMw9t-q8HBuv8II_ssclthjA7sL6jik,3605
94
94
  pixeltable/functions/huggingface.py,sha256=Y-io3EungSs5ibr43vLEXs4dz_Ej20F1nglD0fyLrXA,20371
95
95
  pixeltable/functions/image.py,sha256=IKXljMma-uU88efptC3F4aywau7DYcD-Nqd3YpmRNRw,13971
96
96
  pixeltable/functions/json.py,sha256=d7-AvwytUQtQYF_JnWJkptT_Yq0NgMpWfVk-m3U6qTY,807
@@ -98,7 +98,7 @@ pixeltable/functions/llama_cpp.py,sha256=uop0K6oNxCnQXbdiL-_6PVsusc1xqCtwTipAyIb
98
98
  pixeltable/functions/math.py,sha256=jhlD7v4eY-6KdmsFEBqb-W_vspGahOosUvFahWFzxrU,4969
99
99
  pixeltable/functions/mistralai.py,sha256=Fk52mfWUfxVy-yCxhH6wrGS7nLLSiOOrWxbTkkiQ-O8,5542
100
100
  pixeltable/functions/ollama.py,sha256=4-6h9Foq_7Ut7JtEHGkeg1KbuKaFywSuMrKiw0xAyCA,4231
101
- pixeltable/functions/openai.py,sha256=qeErzHgJ2D5KFhUxnzcqZ2DrvvT2q-UoMp3tNZP5fgg,28782
101
+ pixeltable/functions/openai.py,sha256=tXmT7UwyUbREa44PS9TPiK1xadPx6eQ_zLfDgQL-A9k,28999
102
102
  pixeltable/functions/replicate.py,sha256=sPvRGr0j0kCDc6Vz3mPUioFflApijukvZWJJUO2bqIQ,2429
103
103
  pixeltable/functions/string.py,sha256=LdBNOna5PUSPmM5VlJ_qhmwzyFhumW0k6Dvx2rXSZtc,25356
104
104
  pixeltable/functions/timestamp.py,sha256=3GVCVIWdry96Qk5XXuvbJ58Tp30iY5snBibzl2CHjQc,9143
@@ -124,7 +124,7 @@ pixeltable/io/pandas.py,sha256=xQmkwbqE9_fjbbPUgeG5yNICrbVVK73UHxDL-cgrQw0,9007
124
124
  pixeltable/io/parquet.py,sha256=qoVDuCoW-Tq14IlzN_psoNP7z83hIQ3ZEg_pKzHSqoY,7796
125
125
  pixeltable/io/table_data_conduit.py,sha256=--UWwG6agBtOA5PLPfjxp2XKoAQ-f5nSPJqOgA5DAAI,22062
126
126
  pixeltable/io/utils.py,sha256=qzBTmqdIawXMt2bfXQOraYnEstL69eC2Z33nl8RrwJk,4244
127
- pixeltable/iterators/__init__.py,sha256=bU4EmbX85J1URmRw6G71f2I77b1ctqngEOwDmRB3T0w,455
127
+ pixeltable/iterators/__init__.py,sha256=hI937cmBRU3eWbfJ7miFthAGUo_xmcYciw6gAjOCg9g,470
128
128
  pixeltable/iterators/audio.py,sha256=HYE8JcqaJsTGdrq4NkwV5tn7lcyMp6Fjrm59efOLzb0,9671
129
129
  pixeltable/iterators/base.py,sha256=ZC0ZvXL4iw6AmT8cu-Mdx-T2UG9nmJYV1C6LK4efAfw,1669
130
130
  pixeltable/iterators/document.py,sha256=7NIN5W5jHVm4v5_FzGsH0XJigtPCm8DfXJUc3_hEtHQ,20073
@@ -167,9 +167,9 @@ pixeltable/metadata/converters/convert_39.py,sha256=YaEfgStxtYGRbuRLFw8wTAZVJRzI
167
167
  pixeltable/metadata/converters/util.py,sha256=QUBOj2F_6rCAdIo0lgD1IVgAM15Vmq7ikQspB4s0eQ8,7732
168
168
  pixeltable/mypy/__init__.py,sha256=cD_oHXClR_bDM8qVNIfaOAgRhQjPfcWvLcinz79ua6o,54
169
169
  pixeltable/mypy/mypy_plugin.py,sha256=KCjzKOeKW5CBqJOq9Ch7ZJ25ICPc4nlTB49DxtC6oDM,5460
170
- pixeltable/share/__init__.py,sha256=AtR4nS6YkfkFRkXA-zZXFTK5pSQjHry8MnxdVLUk5SA,68
170
+ pixeltable/share/__init__.py,sha256=PTX1mw61Ss4acEOI-sUlu0HaoVsosLqwDfh0ldn8Hkg,84
171
171
  pixeltable/share/packager.py,sha256=5rSKnQCs3YP5h48d79bXEK4L8tLUSeTSbXaB8X9SmBI,31265
172
- pixeltable/share/publish.py,sha256=KS_R59AuVkHWkXHwELP74xgSHs8Z5z8SBPMcjzttt44,11469
172
+ pixeltable/share/publish.py,sha256=VE_H3ux56gdSHd8_ganxCnNYtxrjaalMPgwAIYmdbE8,11300
173
173
  pixeltable/utils/__init__.py,sha256=45qEM20L2VuIe-Cc3BTKWFqQb-S7A8qDtmmgl77zYK0,1728
174
174
  pixeltable/utils/arrow.py,sha256=Rooa02GL5k--D2utlKATtYKrrlsHbbi6JmkarXMux1M,6384
175
175
  pixeltable/utils/av.py,sha256=omJufz62dzaTTwlR7quKfcT7apf8KkBLJ9cQ9240dt0,4016
@@ -185,14 +185,14 @@ pixeltable/utils/filecache.py,sha256=3TTEqhGg0pEAP_l0GKn34uspC4dha1jPab1Ka9_oTBM
185
185
  pixeltable/utils/formatter.py,sha256=tbMxE9rBw6wdKUnJhNZ8h9uAF8dZKcihQ2KesqAag9A,10096
186
186
  pixeltable/utils/http_server.py,sha256=6khOAtpVj1lDIm9Dx8VIECLm87cFEp4IFbAg8T92A2o,2441
187
187
  pixeltable/utils/iceberg.py,sha256=COeNqqy5RRMkDGLS8CTnaUeAccG10x2fwP3e1veuqIA,522
188
- pixeltable/utils/media_store.py,sha256=HVOuK5JTTvgSH_st0lsapv39Lnu29QGpkKUtZQybBTA,10560
188
+ pixeltable/utils/media_store.py,sha256=-rYfpZOUrWU1YtEFrxdrn9Na0NeyRW3HJYsOdH-kJO4,10898
189
189
  pixeltable/utils/pydantic.py,sha256=-ztUsuRXA7B6bywb5Yy1h5pNQ2DnsT1d0oHMxqtK3WY,2011
190
190
  pixeltable/utils/pytorch.py,sha256=564VHRdDHwD9h0v5lBHEDTJ8c6zx8wuzWYx8ZYjBxlI,3621
191
191
  pixeltable/utils/s3.py,sha256=pxip2MlCqd2Qon2dzJXzfxvwtZyc-BAsjAnLL4J_OXY,587
192
192
  pixeltable/utils/sql.py,sha256=Sa4Lh-VGe8GToU5W7DRiWf2lMl9B6saPqemiT0ZdHEc,806
193
193
  pixeltable/utils/transactional_directory.py,sha256=OFKmu90oP7KwBAljwjnzP_w8euGdAXob3y4Nx9SCNHA,1357
194
- pixeltable-0.4.10.dist-info/METADATA,sha256=I3iYbF6fjvaQwBtbUNqF_KUbvzirqnv21npnqAJmxjc,24248
195
- pixeltable-0.4.10.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
196
- pixeltable-0.4.10.dist-info/entry_points.txt,sha256=rrKugZmxDtGnXCnEQ5UJMaaSYY7-g1cLjUZ4W1moIhM,98
197
- pixeltable-0.4.10.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
198
- pixeltable-0.4.10.dist-info/RECORD,,
194
+ pixeltable-0.4.12.dist-info/METADATA,sha256=mJSdwTquIKJqX6iziu0ZKHMg0guXT1HrGwqNCGvjZJw,24248
195
+ pixeltable-0.4.12.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
196
+ pixeltable-0.4.12.dist-info/entry_points.txt,sha256=rrKugZmxDtGnXCnEQ5UJMaaSYY7-g1cLjUZ4W1moIhM,98
197
+ pixeltable-0.4.12.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
198
+ pixeltable-0.4.12.dist-info/RECORD,,