pixeltable 0.4.18__py3-none-any.whl → 0.4.19__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/__init__.py +1 -1
- pixeltable/_version.py +1 -0
- pixeltable/catalog/catalog.py +119 -100
- pixeltable/catalog/column.py +104 -115
- pixeltable/catalog/globals.py +1 -2
- pixeltable/catalog/insertable_table.py +44 -49
- pixeltable/catalog/path.py +3 -4
- pixeltable/catalog/schema_object.py +4 -4
- pixeltable/catalog/table.py +118 -122
- pixeltable/catalog/table_metadata.py +6 -6
- pixeltable/catalog/table_version.py +322 -257
- pixeltable/catalog/table_version_handle.py +4 -4
- pixeltable/catalog/table_version_path.py +9 -10
- pixeltable/catalog/tbl_ops.py +9 -3
- pixeltable/catalog/view.py +34 -28
- pixeltable/config.py +14 -10
- pixeltable/dataframe.py +68 -77
- pixeltable/env.py +74 -64
- pixeltable/exec/aggregation_node.py +6 -6
- pixeltable/exec/cache_prefetch_node.py +10 -10
- pixeltable/exec/data_row_batch.py +3 -3
- pixeltable/exec/exec_context.py +4 -5
- pixeltable/exec/exec_node.py +5 -5
- pixeltable/exec/expr_eval/evaluators.py +6 -6
- pixeltable/exec/expr_eval/expr_eval_node.py +8 -7
- pixeltable/exec/expr_eval/globals.py +6 -6
- pixeltable/exec/expr_eval/row_buffer.py +1 -2
- pixeltable/exec/expr_eval/schedulers.py +11 -11
- pixeltable/exec/in_memory_data_node.py +2 -2
- pixeltable/exec/object_store_save_node.py +14 -17
- pixeltable/exec/sql_node.py +25 -25
- pixeltable/exprs/arithmetic_expr.py +4 -4
- pixeltable/exprs/array_slice.py +2 -2
- pixeltable/exprs/column_property_ref.py +3 -3
- pixeltable/exprs/column_ref.py +61 -74
- pixeltable/exprs/comparison.py +5 -5
- pixeltable/exprs/compound_predicate.py +3 -3
- pixeltable/exprs/data_row.py +12 -12
- pixeltable/exprs/expr.py +41 -31
- pixeltable/exprs/expr_dict.py +3 -3
- pixeltable/exprs/expr_set.py +3 -3
- pixeltable/exprs/function_call.py +14 -14
- pixeltable/exprs/in_predicate.py +4 -4
- pixeltable/exprs/inline_expr.py +8 -8
- pixeltable/exprs/is_null.py +1 -3
- pixeltable/exprs/json_mapper.py +8 -8
- pixeltable/exprs/json_path.py +6 -6
- pixeltable/exprs/literal.py +5 -5
- pixeltable/exprs/method_ref.py +2 -2
- pixeltable/exprs/object_ref.py +2 -2
- pixeltable/exprs/row_builder.py +14 -14
- pixeltable/exprs/rowid_ref.py +8 -8
- pixeltable/exprs/similarity_expr.py +50 -25
- pixeltable/exprs/sql_element_cache.py +4 -4
- pixeltable/exprs/string_op.py +2 -2
- pixeltable/exprs/type_cast.py +3 -5
- pixeltable/func/aggregate_function.py +8 -8
- pixeltable/func/callable_function.py +9 -9
- pixeltable/func/expr_template_function.py +3 -3
- pixeltable/func/function.py +15 -17
- pixeltable/func/function_registry.py +6 -7
- pixeltable/func/globals.py +2 -3
- pixeltable/func/mcp.py +2 -2
- pixeltable/func/query_template_function.py +16 -16
- pixeltable/func/signature.py +14 -14
- pixeltable/func/tools.py +11 -11
- pixeltable/func/udf.py +16 -18
- pixeltable/functions/__init__.py +1 -0
- pixeltable/functions/anthropic.py +7 -7
- pixeltable/functions/audio.py +76 -0
- pixeltable/functions/bedrock.py +6 -6
- pixeltable/functions/deepseek.py +4 -4
- pixeltable/functions/fireworks.py +2 -2
- pixeltable/functions/gemini.py +6 -6
- pixeltable/functions/globals.py +12 -12
- pixeltable/functions/groq.py +4 -4
- pixeltable/functions/huggingface.py +18 -20
- pixeltable/functions/image.py +7 -10
- pixeltable/functions/llama_cpp.py +7 -7
- pixeltable/functions/math.py +2 -3
- pixeltable/functions/mistralai.py +3 -3
- pixeltable/functions/ollama.py +9 -9
- pixeltable/functions/openai.py +21 -21
- pixeltable/functions/openrouter.py +7 -7
- pixeltable/functions/string.py +21 -28
- pixeltable/functions/timestamp.py +7 -8
- pixeltable/functions/together.py +4 -6
- pixeltable/functions/twelvelabs.py +92 -0
- pixeltable/functions/video.py +2 -24
- pixeltable/functions/vision.py +6 -6
- pixeltable/functions/whisper.py +7 -7
- pixeltable/functions/whisperx.py +16 -16
- pixeltable/globals.py +52 -36
- pixeltable/index/base.py +12 -8
- pixeltable/index/btree.py +19 -22
- pixeltable/index/embedding_index.py +30 -39
- pixeltable/io/datarows.py +3 -3
- pixeltable/io/external_store.py +13 -16
- pixeltable/io/fiftyone.py +5 -5
- pixeltable/io/globals.py +5 -5
- pixeltable/io/hf_datasets.py +4 -4
- pixeltable/io/label_studio.py +12 -12
- pixeltable/io/pandas.py +6 -6
- pixeltable/io/parquet.py +2 -2
- pixeltable/io/table_data_conduit.py +12 -12
- pixeltable/io/utils.py +2 -2
- pixeltable/iterators/audio.py +2 -2
- pixeltable/iterators/video.py +8 -13
- pixeltable/metadata/converters/convert_18.py +2 -2
- pixeltable/metadata/converters/convert_19.py +2 -2
- pixeltable/metadata/converters/convert_20.py +2 -2
- pixeltable/metadata/converters/convert_21.py +2 -2
- pixeltable/metadata/converters/convert_22.py +2 -2
- pixeltable/metadata/converters/convert_24.py +2 -2
- pixeltable/metadata/converters/convert_25.py +2 -2
- pixeltable/metadata/converters/convert_26.py +2 -2
- pixeltable/metadata/converters/convert_29.py +4 -4
- pixeltable/metadata/converters/convert_34.py +2 -2
- pixeltable/metadata/converters/convert_36.py +2 -2
- pixeltable/metadata/converters/convert_38.py +2 -2
- pixeltable/metadata/converters/convert_39.py +1 -2
- pixeltable/metadata/converters/util.py +11 -13
- pixeltable/metadata/schema.py +22 -21
- pixeltable/metadata/utils.py +2 -6
- pixeltable/mypy/mypy_plugin.py +5 -5
- pixeltable/plan.py +30 -28
- pixeltable/share/packager.py +7 -7
- pixeltable/share/publish.py +3 -3
- pixeltable/store.py +125 -61
- pixeltable/type_system.py +43 -46
- pixeltable/utils/__init__.py +1 -2
- pixeltable/utils/arrow.py +4 -4
- pixeltable/utils/av.py +8 -0
- pixeltable/utils/azure_store.py +305 -0
- pixeltable/utils/code.py +1 -2
- pixeltable/utils/dbms.py +15 -19
- pixeltable/utils/description_helper.py +2 -3
- pixeltable/utils/documents.py +5 -6
- pixeltable/utils/exception_handler.py +2 -2
- pixeltable/utils/filecache.py +5 -5
- pixeltable/utils/formatter.py +4 -6
- pixeltable/utils/gcs_store.py +9 -9
- pixeltable/utils/local_store.py +17 -17
- pixeltable/utils/object_stores.py +59 -43
- pixeltable/utils/s3_store.py +35 -30
- {pixeltable-0.4.18.dist-info → pixeltable-0.4.19.dist-info}/METADATA +1 -1
- pixeltable-0.4.19.dist-info/RECORD +213 -0
- pixeltable/__version__.py +0 -3
- pixeltable-0.4.18.dist-info/RECORD +0 -211
- {pixeltable-0.4.18.dist-info → pixeltable-0.4.19.dist-info}/WHEEL +0 -0
- {pixeltable-0.4.18.dist-info → pixeltable-0.4.19.dist-info}/entry_points.txt +0 -0
- {pixeltable-0.4.18.dist-info → pixeltable-0.4.19.dist-info}/licenses/LICENSE +0 -0
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
4
|
from dataclasses import dataclass
|
|
5
|
-
from typing import TYPE_CHECKING
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
6
|
from uuid import UUID
|
|
7
7
|
|
|
8
8
|
from pixeltable import exceptions as excs
|
|
@@ -21,10 +21,10 @@ class TableVersionHandle:
|
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
23
|
id: UUID
|
|
24
|
-
effective_version:
|
|
25
|
-
_tbl_version:
|
|
24
|
+
effective_version: int | None
|
|
25
|
+
_tbl_version: TableVersion | None
|
|
26
26
|
|
|
27
|
-
def __init__(self, tbl_id: UUID, effective_version:
|
|
27
|
+
def __init__(self, tbl_id: UUID, effective_version: int | None, tbl_version: TableVersion | None = None):
|
|
28
28
|
self.id = tbl_id
|
|
29
29
|
self.effective_version = effective_version
|
|
30
30
|
self._tbl_version = tbl_version
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
from typing import Optional
|
|
5
4
|
from uuid import UUID
|
|
6
5
|
|
|
7
6
|
from pixeltable.env import Env
|
|
@@ -39,10 +38,10 @@ class TableVersionPath:
|
|
|
39
38
|
"""
|
|
40
39
|
|
|
41
40
|
tbl_version: TableVersionHandle
|
|
42
|
-
base:
|
|
43
|
-
_cached_tbl_version:
|
|
41
|
+
base: TableVersionPath | None
|
|
42
|
+
_cached_tbl_version: TableVersion | None
|
|
44
43
|
|
|
45
|
-
def __init__(self, tbl_version: TableVersionHandle, base:
|
|
44
|
+
def __init__(self, tbl_version: TableVersionHandle, base: TableVersionPath | None = None):
|
|
46
45
|
assert tbl_version is not None
|
|
47
46
|
self.tbl_version = tbl_version
|
|
48
47
|
self.base = base
|
|
@@ -51,7 +50,7 @@ class TableVersionPath:
|
|
|
51
50
|
@classmethod
|
|
52
51
|
def from_md(cls, path: schema.TableVersionPath) -> TableVersionPath:
|
|
53
52
|
assert len(path) > 0
|
|
54
|
-
result:
|
|
53
|
+
result: TableVersionPath | None = None
|
|
55
54
|
for tbl_id_str, effective_version in path[::-1]:
|
|
56
55
|
tbl_id = UUID(tbl_id_str)
|
|
57
56
|
result = TableVersionPath(TableVersionHandle(tbl_id, effective_version), base=result)
|
|
@@ -156,7 +155,7 @@ class TableVersionPath:
|
|
|
156
155
|
return []
|
|
157
156
|
return self.base.get_tbl_versions()
|
|
158
157
|
|
|
159
|
-
def find_tbl_version(self, id: UUID) ->
|
|
158
|
+
def find_tbl_version(self, id: UUID) -> TableVersionHandle | None:
|
|
160
159
|
"""Return the matching TableVersion in the chain of TableVersions, starting with this one"""
|
|
161
160
|
if self.tbl_version.id == id:
|
|
162
161
|
return self.tbl_version
|
|
@@ -184,7 +183,7 @@ class TableVersionPath:
|
|
|
184
183
|
cols = self.columns()
|
|
185
184
|
return {col.id: col for col in cols}
|
|
186
185
|
|
|
187
|
-
def get_column(self, name: str) ->
|
|
186
|
+
def get_column(self, name: str) -> Column | None:
|
|
188
187
|
"""Return the column with the given name, or None if not found"""
|
|
189
188
|
self.refresh_cached_md()
|
|
190
189
|
col = self._cached_tbl_version.cols_by_name.get(name)
|
|
@@ -197,12 +196,12 @@ class TableVersionPath:
|
|
|
197
196
|
|
|
198
197
|
def has_column(self, col: Column) -> bool:
|
|
199
198
|
"""Return True if this table has the given column."""
|
|
200
|
-
assert col.
|
|
199
|
+
assert col.get_tbl() is not None
|
|
201
200
|
self.refresh_cached_md()
|
|
202
201
|
|
|
203
202
|
if (
|
|
204
|
-
col.
|
|
205
|
-
and col.
|
|
203
|
+
col.get_tbl().id == self.tbl_version.id
|
|
204
|
+
and col.get_tbl().effective_version == self.tbl_version.effective_version
|
|
206
205
|
and col.id in self._cached_tbl_version.cols_by_id
|
|
207
206
|
):
|
|
208
207
|
# the column is visible in this table version
|
pixeltable/catalog/tbl_ops.py
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# TableVersion
|
|
6
6
|
|
|
7
7
|
import dataclasses
|
|
8
|
-
from typing import Any
|
|
8
|
+
from typing import Any
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
@dataclasses.dataclass
|
|
@@ -13,6 +13,11 @@ class CreateStoreTableOp:
|
|
|
13
13
|
pass
|
|
14
14
|
|
|
15
15
|
|
|
16
|
+
@dataclasses.dataclass
|
|
17
|
+
class CreateIndexOp:
|
|
18
|
+
idx_id: int
|
|
19
|
+
|
|
20
|
+
|
|
16
21
|
@dataclasses.dataclass
|
|
17
22
|
class LoadViewOp:
|
|
18
23
|
view_path: dict[str, Any] # needed to create the view load plan
|
|
@@ -40,5 +45,6 @@ class TableOp:
|
|
|
40
45
|
num_ops: int # total number of ops forming the update operation
|
|
41
46
|
needs_xact: bool # if True, op must be run as part of a transaction
|
|
42
47
|
|
|
43
|
-
create_store_table_op:
|
|
44
|
-
|
|
48
|
+
create_store_table_op: CreateStoreTableOp | None = None
|
|
49
|
+
create_index_op: CreateIndexOp | None = None
|
|
50
|
+
load_view_op: LoadViewOp | None = None
|
pixeltable/catalog/view.py
CHANGED
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import inspect
|
|
4
4
|
import logging
|
|
5
|
-
from typing import TYPE_CHECKING, Any, List, Literal
|
|
5
|
+
from typing import TYPE_CHECKING, Any, List, Literal
|
|
6
6
|
from uuid import UUID
|
|
7
7
|
|
|
8
8
|
import pixeltable.exceptions as excs
|
|
@@ -11,10 +11,6 @@ import pixeltable.type_system as ts
|
|
|
11
11
|
from pixeltable import catalog, exprs, func
|
|
12
12
|
from pixeltable.iterators import ComponentIterator
|
|
13
13
|
|
|
14
|
-
if TYPE_CHECKING:
|
|
15
|
-
from pixeltable.plan import SampleClause
|
|
16
|
-
|
|
17
|
-
|
|
18
14
|
from .column import Column
|
|
19
15
|
from .globals import _POS_COLUMN_NAME, MediaValidation
|
|
20
16
|
from .table import Table
|
|
@@ -27,6 +23,7 @@ from .update_status import UpdateStatus
|
|
|
27
23
|
if TYPE_CHECKING:
|
|
28
24
|
from pixeltable.catalog.table import TableMetadata
|
|
29
25
|
from pixeltable.globals import TableDataSource
|
|
26
|
+
from pixeltable.plan import SampleClause
|
|
30
27
|
|
|
31
28
|
_logger = logging.getLogger('pixeltable')
|
|
32
29
|
|
|
@@ -56,7 +53,7 @@ class View(Table):
|
|
|
56
53
|
return 'table'
|
|
57
54
|
|
|
58
55
|
@classmethod
|
|
59
|
-
def select_list_to_additional_columns(cls, select_list: list[tuple[exprs.Expr,
|
|
56
|
+
def select_list_to_additional_columns(cls, select_list: list[tuple[exprs.Expr, str | None]]) -> dict[str, dict]:
|
|
60
57
|
"""Returns a list of columns in the same format as the additional_columns parameter of View.create.
|
|
61
58
|
The source is the list of expressions from a select() statement on a DataFrame.
|
|
62
59
|
If the column is a ColumnRef, to a base table column, it is marked to not be stored.sy
|
|
@@ -76,17 +73,18 @@ class View(Table):
|
|
|
76
73
|
dir_id: UUID,
|
|
77
74
|
name: str,
|
|
78
75
|
base: TableVersionPath,
|
|
79
|
-
select_list:
|
|
76
|
+
select_list: list[tuple[exprs.Expr, str | None]] | None,
|
|
80
77
|
additional_columns: dict[str, Any],
|
|
81
|
-
predicate:
|
|
82
|
-
sample_clause:
|
|
78
|
+
predicate: 'exprs.Expr' | None,
|
|
79
|
+
sample_clause: 'SampleClause' | None,
|
|
83
80
|
is_snapshot: bool,
|
|
81
|
+
create_default_idxs: bool,
|
|
84
82
|
num_retained_versions: int,
|
|
85
83
|
comment: str,
|
|
86
84
|
media_validation: MediaValidation,
|
|
87
|
-
iterator_cls:
|
|
88
|
-
iterator_args:
|
|
89
|
-
) -> tuple[TableVersionMd,
|
|
85
|
+
iterator_cls: type[ComponentIterator] | None,
|
|
86
|
+
iterator_args: dict | None,
|
|
87
|
+
) -> tuple[TableVersionMd, list[TableOp] | None]:
|
|
90
88
|
from pixeltable.plan import SampleClause
|
|
91
89
|
|
|
92
90
|
# Convert select_list to more additional_columns if present
|
|
@@ -103,7 +101,7 @@ class View(Table):
|
|
|
103
101
|
# verify that filters can be evaluated in the context of the base
|
|
104
102
|
if predicate is not None:
|
|
105
103
|
if not predicate.is_bound_by([base]):
|
|
106
|
-
raise excs.Error(f'
|
|
104
|
+
raise excs.Error(f'View filter cannot be computed in the context of the base table {base.tbl_name()!r}')
|
|
107
105
|
# create a copy that we can modify and store
|
|
108
106
|
predicate = predicate.copy()
|
|
109
107
|
if sample_clause is not None:
|
|
@@ -111,7 +109,9 @@ class View(Table):
|
|
|
111
109
|
if sample_clause.stratify_exprs is not None and not all(
|
|
112
110
|
stratify_expr.is_bound_by([base]) for stratify_expr in sample_clause.stratify_exprs
|
|
113
111
|
):
|
|
114
|
-
raise excs.Error(
|
|
112
|
+
raise excs.Error(
|
|
113
|
+
f'View sample clause cannot be computed in the context of the base table {base.tbl_name()!r}'
|
|
114
|
+
)
|
|
115
115
|
# create a copy that we can modify and store
|
|
116
116
|
sc = sample_clause
|
|
117
117
|
sample_clause = SampleClause(
|
|
@@ -125,8 +125,8 @@ class View(Table):
|
|
|
125
125
|
# make sure that the value can be computed in the context of the base
|
|
126
126
|
if col.value_expr is not None and not col.value_expr.is_bound_by([base]):
|
|
127
127
|
raise excs.Error(
|
|
128
|
-
f'Column {col.name}:
|
|
129
|
-
f'base {base.tbl_name()}'
|
|
128
|
+
f'Column {col.name!r}: Value expression cannot be computed in the context of the '
|
|
129
|
+
f'base table {base.tbl_name()!r}'
|
|
130
130
|
)
|
|
131
131
|
|
|
132
132
|
if iterator_cls is not None:
|
|
@@ -153,18 +153,18 @@ class View(Table):
|
|
|
153
153
|
sig = func.Signature(ts.InvalidType(), params)
|
|
154
154
|
|
|
155
155
|
expr_args = {k: exprs.Expr.from_object(v) for k, v in bound_args.items()}
|
|
156
|
-
sig.validate_args(expr_args, context=f'in iterator {iterator_cls.__name__
|
|
156
|
+
sig.validate_args(expr_args, context=f'in iterator of type `{iterator_cls.__name__}`')
|
|
157
157
|
literal_args = {k: v.val if isinstance(v, exprs.Literal) else v for k, v in expr_args.items()}
|
|
158
158
|
|
|
159
159
|
# prepend pos and output_schema columns to cols:
|
|
160
160
|
# a component view exposes the pos column of its rowid;
|
|
161
161
|
# we create that column here, so it gets assigned a column id;
|
|
162
162
|
# stored=False: it is not stored separately (it's already stored as part of the rowid)
|
|
163
|
-
iterator_cols = [Column(_POS_COLUMN_NAME, ts.IntType(), stored=False)]
|
|
163
|
+
iterator_cols = [Column(_POS_COLUMN_NAME, ts.IntType(), is_iterator_col=True, stored=False)]
|
|
164
164
|
output_dict, unstored_cols = iterator_cls.output_schema(**literal_args)
|
|
165
165
|
iterator_cols.extend(
|
|
166
166
|
[
|
|
167
|
-
Column(col_name, col_type, stored=col_name not in unstored_cols)
|
|
167
|
+
Column(col_name, col_type, is_iterator_col=True, stored=col_name not in unstored_cols)
|
|
168
168
|
for col_name, col_type in output_dict.items()
|
|
169
169
|
]
|
|
170
170
|
)
|
|
@@ -206,7 +206,13 @@ class View(Table):
|
|
|
206
206
|
)
|
|
207
207
|
|
|
208
208
|
md = TableVersion.create_initial_md(
|
|
209
|
-
name,
|
|
209
|
+
name,
|
|
210
|
+
columns,
|
|
211
|
+
num_retained_versions,
|
|
212
|
+
comment,
|
|
213
|
+
media_validation=media_validation,
|
|
214
|
+
view_md=view_md,
|
|
215
|
+
create_default_idxs=create_default_idxs,
|
|
210
216
|
)
|
|
211
217
|
if md.tbl_md.is_pure_snapshot:
|
|
212
218
|
# this is purely a snapshot: no store table to create or load
|
|
@@ -230,7 +236,7 @@ class View(Table):
|
|
|
230
236
|
def _verify_column(cls, col: Column) -> None:
|
|
231
237
|
# make sure that columns are nullable or have a default
|
|
232
238
|
if not col.col_type.nullable and not col.is_computed:
|
|
233
|
-
raise excs.Error(f'Column {col.name}:
|
|
239
|
+
raise excs.Error(f'Column {col.name!r}: Non-computed columns in views must be nullable')
|
|
234
240
|
super()._verify_column(col)
|
|
235
241
|
|
|
236
242
|
@classmethod
|
|
@@ -282,22 +288,22 @@ class View(Table):
|
|
|
282
288
|
|
|
283
289
|
def insert(
|
|
284
290
|
self,
|
|
285
|
-
source:
|
|
291
|
+
source: TableDataSource | None = None,
|
|
286
292
|
/,
|
|
287
293
|
*,
|
|
288
|
-
source_format:
|
|
289
|
-
schema_overrides:
|
|
294
|
+
source_format: Literal['csv', 'excel', 'parquet', 'json'] | None = None,
|
|
295
|
+
schema_overrides: dict[str, ts.ColumnType] | None = None,
|
|
290
296
|
on_error: Literal['abort', 'ignore'] = 'abort',
|
|
291
297
|
print_stats: bool = False,
|
|
292
298
|
**kwargs: Any,
|
|
293
299
|
) -> UpdateStatus:
|
|
294
300
|
raise excs.Error(f'{self._display_str()}: Cannot insert into a {self._display_name()}.')
|
|
295
301
|
|
|
296
|
-
def delete(self, where:
|
|
302
|
+
def delete(self, where: exprs.Expr | None = None) -> UpdateStatus:
|
|
297
303
|
raise excs.Error(f'{self._display_str()}: Cannot delete from a {self._display_name()}.')
|
|
298
304
|
|
|
299
305
|
@property
|
|
300
|
-
def _base_tbl_id(self) ->
|
|
306
|
+
def _base_tbl_id(self) -> UUID | None:
|
|
301
307
|
if self._tbl_version_path.tbl_id != self._id:
|
|
302
308
|
# _tbl_version_path represents a different schema object from this one. This can only happen if this is a
|
|
303
309
|
# named pure snapshot.
|
|
@@ -306,14 +312,14 @@ class View(Table):
|
|
|
306
312
|
return None
|
|
307
313
|
return self._tbl_version_path.base.tbl_id
|
|
308
314
|
|
|
309
|
-
def _get_base_table(self) ->
|
|
315
|
+
def _get_base_table(self) -> 'Table' | None:
|
|
310
316
|
"""Returns None if there is no base table, or if the base table is hidden."""
|
|
311
317
|
base_tbl_id = self._base_tbl_id
|
|
312
318
|
with catalog.Catalog.get().begin_xact(tbl_id=base_tbl_id, for_write=False):
|
|
313
319
|
return catalog.Catalog.get().get_table_by_id(base_tbl_id)
|
|
314
320
|
|
|
315
321
|
@property
|
|
316
|
-
def _effective_base_versions(self) -> list[
|
|
322
|
+
def _effective_base_versions(self) -> list[int | None]:
|
|
317
323
|
effective_versions = [tv.effective_version for tv in self._tbl_version_path.get_tbl_versions()]
|
|
318
324
|
if self._snapshot_only and not self._is_anonymous_snapshot():
|
|
319
325
|
return effective_versions # Named pure snapshot
|
pixeltable/config.py
CHANGED
|
@@ -4,7 +4,7 @@ import logging
|
|
|
4
4
|
import os
|
|
5
5
|
import shutil
|
|
6
6
|
from pathlib import Path
|
|
7
|
-
from typing import Any, ClassVar,
|
|
7
|
+
from typing import Any, ClassVar, TypeVar
|
|
8
8
|
|
|
9
9
|
import toml
|
|
10
10
|
|
|
@@ -21,7 +21,7 @@ class Config:
|
|
|
21
21
|
configuration values, which can be set in the config file or as environment variables.
|
|
22
22
|
"""
|
|
23
23
|
|
|
24
|
-
__instance: ClassVar[
|
|
24
|
+
__instance: ClassVar[Config | None] = None
|
|
25
25
|
|
|
26
26
|
__home: Path
|
|
27
27
|
__config_file: Path
|
|
@@ -110,7 +110,7 @@ class Config:
|
|
|
110
110
|
return os.environ[env_var]
|
|
111
111
|
return default
|
|
112
112
|
|
|
113
|
-
def get_value(self, key: str, expected_type: type[T], section: str = 'pixeltable') ->
|
|
113
|
+
def get_value(self, key: str, expected_type: type[T], section: str = 'pixeltable') -> T | None:
|
|
114
114
|
value: Any = self.lookup_env(section, key) # Try to get from environment first
|
|
115
115
|
# Next try the config file
|
|
116
116
|
if value is None:
|
|
@@ -131,22 +131,22 @@ class Config:
|
|
|
131
131
|
try:
|
|
132
132
|
if expected_type is bool and isinstance(value, str):
|
|
133
133
|
if value.lower() not in ('true', 'false'):
|
|
134
|
-
raise excs.Error(f
|
|
134
|
+
raise excs.Error(f"Invalid value for configuration parameter '{section}.{key}': {value}")
|
|
135
135
|
return value.lower() == 'true' # type: ignore[return-value]
|
|
136
136
|
return expected_type(value) # type: ignore[call-arg]
|
|
137
137
|
except (ValueError, TypeError) as exc:
|
|
138
|
-
raise excs.Error(f
|
|
138
|
+
raise excs.Error(f"Invalid value for configuration parameter '{section}.{key}': {value}") from exc
|
|
139
139
|
|
|
140
|
-
def get_string_value(self, key: str, section: str = 'pixeltable') ->
|
|
140
|
+
def get_string_value(self, key: str, section: str = 'pixeltable') -> str | None:
|
|
141
141
|
return self.get_value(key, str, section)
|
|
142
142
|
|
|
143
|
-
def get_int_value(self, key: str, section: str = 'pixeltable') ->
|
|
143
|
+
def get_int_value(self, key: str, section: str = 'pixeltable') -> int | None:
|
|
144
144
|
return self.get_value(key, int, section)
|
|
145
145
|
|
|
146
|
-
def get_float_value(self, key: str, section: str = 'pixeltable') ->
|
|
146
|
+
def get_float_value(self, key: str, section: str = 'pixeltable') -> float | None:
|
|
147
147
|
return self.get_value(key, float, section)
|
|
148
148
|
|
|
149
|
-
def get_bool_value(self, key: str, section: str = 'pixeltable') ->
|
|
149
|
+
def get_bool_value(self, key: str, section: str = 'pixeltable') -> bool | None:
|
|
150
150
|
return self.get_value(key, bool, section)
|
|
151
151
|
|
|
152
152
|
|
|
@@ -161,18 +161,21 @@ KNOWN_CONFIG_OPTIONS = {
|
|
|
161
161
|
'hide_warnings': 'Hide warnings from the console',
|
|
162
162
|
'verbosity': 'Verbosity level for console output',
|
|
163
163
|
'api_key': 'API key for Pixeltable cloud',
|
|
164
|
+
'input_media_dest': 'Default destination URI for input media data',
|
|
165
|
+
'output_media_dest': 'Default destination URI for output (computed) media data',
|
|
164
166
|
'r2_profile': 'AWS config profile name used to access R2 storage',
|
|
165
167
|
's3_profile': 'AWS config profile name used to access S3 storage',
|
|
166
168
|
'b2_profile': 'S3-compatible profile name used to access Backblaze B2 storage',
|
|
167
169
|
},
|
|
168
170
|
'anthropic': {'api_key': 'Anthropic API key'},
|
|
171
|
+
'azure': {'storage_account_name': 'Azure storage account name', 'storage_account_key': 'Azure storage account key'},
|
|
169
172
|
'bedrock': {'api_key': 'AWS Bedrock API key'},
|
|
170
173
|
'deepseek': {'api_key': 'Deepseek API key', 'rate_limit': 'Rate limit for Deepseek API requests'},
|
|
171
174
|
'fireworks': {'api_key': 'Fireworks API key', 'rate_limit': 'Rate limit for Fireworks API requests'},
|
|
175
|
+
'twelvelabs': {'api_key': 'TwelveLabs API key', 'rate_limit': 'Rate limit for TwelveLabs API requests'},
|
|
172
176
|
'gemini': {'api_key': 'Gemini API key', 'rate_limits': 'Per-model rate limits for Gemini API requests'},
|
|
173
177
|
'hf': {'auth_token': 'Hugging Face access token'},
|
|
174
178
|
'imagen': {'rate_limits': 'Per-model rate limits for Imagen API requests'},
|
|
175
|
-
'veo': {'rate_limits': 'Per-model rate limits for Veo API requests'},
|
|
176
179
|
'groq': {'api_key': 'Groq API key', 'rate_limit': 'Rate limit for Groq API requests'},
|
|
177
180
|
'label_studio': {'api_key': 'Label Studio API key', 'url': 'Label Studio server URL'},
|
|
178
181
|
'mistral': {'api_key': 'Mistral API key', 'rate_limit': 'Rate limit for Mistral API requests'},
|
|
@@ -193,6 +196,7 @@ KNOWN_CONFIG_OPTIONS = {
|
|
|
193
196
|
'api_key': 'Together API key',
|
|
194
197
|
'rate_limits': 'Per-model category rate limits for Together API requests',
|
|
195
198
|
},
|
|
199
|
+
'veo': {'rate_limits': 'Per-model rate limits for Veo API requests'},
|
|
196
200
|
'pypi': {'api_key': 'PyPI API key (for internal use only)'},
|
|
197
201
|
}
|
|
198
202
|
|