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.
- pixeltable/catalog/table.py +16 -2
- pixeltable/catalog/table_version.py +23 -26
- pixeltable/catalog/view.py +3 -1
- pixeltable/dataframe.py +29 -8
- pixeltable/env.py +1 -6
- pixeltable/exprs/compound_predicate.py +2 -1
- pixeltable/functions/anthropic.py +17 -6
- pixeltable/functions/groq.py +2 -2
- pixeltable/functions/openai.py +6 -3
- pixeltable/globals.py +8 -3
- pixeltable/iterators/__init__.py +1 -1
- pixeltable/share/__init__.py +1 -1
- pixeltable/share/publish.py +12 -10
- pixeltable/utils/media_store.py +11 -0
- {pixeltable-0.4.10.dist-info → pixeltable-0.4.12.dist-info}/METADATA +1 -1
- {pixeltable-0.4.10.dist-info → pixeltable-0.4.12.dist-info}/RECORD +19 -19
- {pixeltable-0.4.10.dist-info → pixeltable-0.4.12.dist-info}/WHEEL +0 -0
- {pixeltable-0.4.10.dist-info → pixeltable-0.4.12.dist-info}/entry_points.txt +0 -0
- {pixeltable-0.4.10.dist-info → pixeltable-0.4.12.dist-info}/licenses/LICENSE +0 -0
pixeltable/catalog/table.py
CHANGED
|
@@ -1478,12 +1478,17 @@ class Table(SchemaObject):
|
|
|
1478
1478
|
return result
|
|
1479
1479
|
|
|
1480
1480
|
def recompute_columns(
|
|
1481
|
-
self,
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
|
1146
|
-
"""
|
|
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
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
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
|
-
|
|
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}')
|
pixeltable/catalog/view.py
CHANGED
|
@@ -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
|
-
|
|
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
|
-
>>>
|
|
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
|
-
>>>
|
|
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
|
-
|
|
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
|
-
>>>
|
|
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]) ->
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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 = (
|
|
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 = (
|
|
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)
|
|
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
|
|
pixeltable/functions/groq.py
CHANGED
|
@@ -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 `
|
|
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='
|
|
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 = {}
|
pixeltable/functions/openai.py
CHANGED
|
@@ -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[
|
|
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
|
-
|
|
546
|
-
|
|
547
|
-
|
|
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':
|
pixeltable/iterators/__init__.py
CHANGED
|
@@ -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'}
|
pixeltable/share/__init__.py
CHANGED
pixeltable/share/publish.py
CHANGED
|
@@ -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
|
-
|
|
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=
|
|
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=
|
|
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=
|
|
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
|
pixeltable/utils/media_store.py
CHANGED
|
@@ -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.
|
|
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=
|
|
5
|
-
pixeltable/env.py,sha256=
|
|
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=
|
|
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=
|
|
22
|
-
pixeltable/catalog/table_version.py,sha256=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
170
|
+
pixeltable/share/__init__.py,sha256=PTX1mw61Ss4acEOI-sUlu0HaoVsosLqwDfh0ldn8Hkg,84
|
|
171
171
|
pixeltable/share/packager.py,sha256=5rSKnQCs3YP5h48d79bXEK4L8tLUSeTSbXaB8X9SmBI,31265
|
|
172
|
-
pixeltable/share/publish.py,sha256=
|
|
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
|
|
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.
|
|
195
|
-
pixeltable-0.4.
|
|
196
|
-
pixeltable-0.4.
|
|
197
|
-
pixeltable-0.4.
|
|
198
|
-
pixeltable-0.4.
|
|
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,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|