pixeltable 0.4.0rc1__py3-none-any.whl → 0.4.0rc3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pixeltable might be problematic. Click here for more details.

Files changed (37) hide show
  1. pixeltable/__version__.py +2 -2
  2. pixeltable/catalog/catalog.py +4 -0
  3. pixeltable/catalog/table.py +16 -0
  4. pixeltable/catalog/table_version.py +17 -2
  5. pixeltable/catalog/view.py +24 -1
  6. pixeltable/dataframe.py +185 -9
  7. pixeltable/env.py +2 -0
  8. pixeltable/exec/__init__.py +1 -1
  9. pixeltable/exec/expr_eval/evaluators.py +4 -1
  10. pixeltable/exec/sql_node.py +152 -12
  11. pixeltable/exprs/data_row.py +5 -3
  12. pixeltable/exprs/expr.py +7 -0
  13. pixeltable/exprs/literal.py +2 -0
  14. pixeltable/func/tools.py +1 -1
  15. pixeltable/functions/anthropic.py +19 -45
  16. pixeltable/functions/deepseek.py +19 -38
  17. pixeltable/functions/fireworks.py +9 -18
  18. pixeltable/functions/gemini.py +2 -3
  19. pixeltable/functions/llama_cpp.py +6 -6
  20. pixeltable/functions/mistralai.py +15 -41
  21. pixeltable/functions/ollama.py +1 -1
  22. pixeltable/functions/openai.py +82 -165
  23. pixeltable/functions/together.py +22 -80
  24. pixeltable/globals.py +5 -0
  25. pixeltable/metadata/__init__.py +11 -2
  26. pixeltable/metadata/converters/convert_36.py +38 -0
  27. pixeltable/metadata/notes.py +1 -0
  28. pixeltable/metadata/schema.py +3 -0
  29. pixeltable/plan.py +217 -10
  30. pixeltable/share/packager.py +115 -6
  31. pixeltable/utils/formatter.py +64 -42
  32. pixeltable/utils/sample.py +25 -0
  33. {pixeltable-0.4.0rc1.dist-info → pixeltable-0.4.0rc3.dist-info}/METADATA +2 -1
  34. {pixeltable-0.4.0rc1.dist-info → pixeltable-0.4.0rc3.dist-info}/RECORD +37 -35
  35. {pixeltable-0.4.0rc1.dist-info → pixeltable-0.4.0rc3.dist-info}/LICENSE +0 -0
  36. {pixeltable-0.4.0rc1.dist-info → pixeltable-0.4.0rc3.dist-info}/WHEEL +0 -0
  37. {pixeltable-0.4.0rc1.dist-info → pixeltable-0.4.0rc3.dist-info}/entry_points.txt +0 -0
@@ -1,4 +1,7 @@
1
+ import base64
1
2
  import datetime
3
+ import io
4
+ import itertools
2
5
  import json
3
6
  import logging
4
7
  import tarfile
@@ -10,15 +13,18 @@ from typing import Any, Iterator, Optional
10
13
  from uuid import UUID
11
14
 
12
15
  import more_itertools
16
+ import numpy as np
17
+ import PIL.Image
13
18
  import pyarrow as pa
14
19
  import pyarrow.parquet as pq
15
20
  import sqlalchemy as sql
16
21
 
17
22
  import pixeltable as pxt
18
- from pixeltable import catalog, exceptions as excs, metadata
23
+ from pixeltable import catalog, exceptions as excs, metadata, type_system as ts
19
24
  from pixeltable.env import Env
20
25
  from pixeltable.metadata import schema
21
26
  from pixeltable.utils import sha256sum
27
+ from pixeltable.utils.formatter import Formatter
22
28
  from pixeltable.utils.media_store import MediaStore
23
29
 
24
30
  _logger = logging.getLogger('pixeltable')
@@ -46,6 +52,10 @@ class TablePackager:
46
52
  media_files: dict[Path, str] # Mapping from local media file paths to their tarball names
47
53
  md: dict[str, Any]
48
54
 
55
+ bundle_path: Path
56
+ preview_header: dict[str, str]
57
+ preview: list[list[Any]]
58
+
49
59
  def __init__(self, table: catalog.Table, additional_md: Optional[dict[str, Any]] = None) -> None:
50
60
  self.table = table
51
61
  self.tmp_dir = Path(Env.get().create_tmp_path())
@@ -67,7 +77,8 @@ class TablePackager:
67
77
  Export the table to a tarball containing Parquet tables and media files.
68
78
  """
69
79
  assert not self.tmp_dir.exists() # Packaging can only be done once per TablePackager instance
70
- _logger.info(f"Packaging table '{self.table._path()}' and its ancestors in: {self.tmp_dir}")
80
+
81
+ _logger.info(f'Packaging table {self.table._path()!r} and its ancestors in: {self.tmp_dir}')
71
82
  self.tmp_dir.mkdir()
72
83
  with open(self.tmp_dir / 'metadata.json', 'w', encoding='utf8') as fp:
73
84
  json.dump(self.md, fp)
@@ -75,12 +86,20 @@ class TablePackager:
75
86
  self.tables_dir.mkdir()
76
87
  with catalog.Catalog.get().begin_xact(for_write=False):
77
88
  for tv in self.table._tbl_version_path.get_tbl_versions():
78
- _logger.info(f"Exporting table '{tv.get().versioned_name}'.")
89
+ _logger.info(f'Exporting table {tv.get().versioned_name!r}.')
79
90
  self.__export_table(tv.get())
91
+
80
92
  _logger.info('Building archive.')
81
- bundle_path = self.__build_tarball()
82
- _logger.info(f'Packaging complete: {bundle_path}')
83
- return bundle_path
93
+ self.bundle_path = self.__build_tarball()
94
+
95
+ _logger.info('Extracting preview data.')
96
+ self.md['count'] = self.table.count()
97
+ preview_header, preview = self.__extract_preview_data()
98
+ self.md['preview_header'] = preview_header
99
+ self.md['preview'] = preview
100
+
101
+ _logger.info(f'Packaging complete: {self.bundle_path}')
102
+ return self.bundle_path
84
103
 
85
104
  def __export_table(self, tv: catalog.TableVersion) -> None:
86
105
  """
@@ -207,6 +226,96 @@ class TablePackager:
207
226
  tf.add(src_file, arcname=f'media/{dest_name}')
208
227
  return bundle_path
209
228
 
229
+ def __extract_preview_data(self) -> tuple[dict[str, str], list[list[Any]]]:
230
+ """
231
+ Extract a preview of the table data for display in the UI.
232
+
233
+ In order to bound the size of the output data, all "unbounded" data types are resized:
234
+ - Strings are abbreviated as per Formatter.abbreviate()
235
+ - Arrays and JSON are shortened and formatted as strings
236
+ - Images are resized to thumbnail size as a base64-encoded webp
237
+ - Videos are replaced by their first frame and resized as above
238
+ - Documents are replaced by a thumbnail as a base64-encoded webp
239
+ """
240
+ # First 8 columns
241
+ preview_cols = dict(itertools.islice(self.table._schema.items(), 0, 8))
242
+ select_list = [self.table[col_name] for col_name in preview_cols]
243
+ # First 5 rows
244
+ rows = list(self.table.select(*select_list).head(n=5))
245
+
246
+ preview_header = {col_name: str(col_type._type) for col_name, col_type in preview_cols.items()}
247
+ preview = [
248
+ [self.__encode_preview_data(val, col_type)]
249
+ for row in rows
250
+ for val, col_type in zip(row.values(), preview_cols.values())
251
+ ]
252
+
253
+ return preview_header, preview
254
+
255
+ def __encode_preview_data(self, val: Any, col_type: ts.ColumnType) -> Any:
256
+ if val is None:
257
+ return None
258
+
259
+ match col_type._type:
260
+ case ts.ColumnType.Type.STRING:
261
+ assert isinstance(val, str)
262
+ return Formatter.abbreviate(val)
263
+
264
+ case ts.ColumnType.Type.INT | ts.ColumnType.Type.FLOAT | ts.ColumnType.Type.BOOL:
265
+ return val
266
+
267
+ case ts.ColumnType.Type.TIMESTAMP | ts.ColumnType.Type.DATE:
268
+ return str(val)
269
+
270
+ case ts.ColumnType.Type.ARRAY:
271
+ assert isinstance(val, np.ndarray)
272
+ return Formatter.format_array(val)
273
+
274
+ case ts.ColumnType.Type.JSON:
275
+ # We need to escape the JSON string server-side for security reasons.
276
+ # Therefore we don't escape it here, in order to avoid double-escaping.
277
+ return Formatter.format_json(val, escape_strings=False)
278
+
279
+ case ts.ColumnType.Type.IMAGE:
280
+ # Rescale the image to minimize data transfer size
281
+ assert isinstance(val, PIL.Image.Image)
282
+ return self.__encode_image(val)
283
+
284
+ case ts.ColumnType.Type.VIDEO:
285
+ assert isinstance(val, str)
286
+ return self.__encode_video(val)
287
+
288
+ case ts.ColumnType.Type.AUDIO:
289
+ return None
290
+
291
+ case ts.ColumnType.Type.DOCUMENT:
292
+ assert isinstance(val, str)
293
+ return self.__encode_document(val)
294
+
295
+ case _:
296
+ raise AssertionError(f'Unrecognized column type: {col_type._type}')
297
+
298
+ def __encode_image(self, img: PIL.Image.Image) -> str:
299
+ # Heuristic for thumbnail sizing:
300
+ # Standardize on a width of 240 pixels (to most efficiently utilize the columnar display).
301
+ # But, if the aspect ratio is below 2:3, bound the height at 360 pixels (to avoid unboundedly tall thumbnails
302
+ # in the case of highly oblong images).
303
+ if img.height > img.width * 1.5:
304
+ scaled_img = img.resize((img.width * 360 // img.height, 360))
305
+ else:
306
+ scaled_img = img.resize((240, img.height * 240 // img.width))
307
+ with io.BytesIO() as buffer:
308
+ scaled_img.save(buffer, 'webp')
309
+ return base64.b64encode(buffer.getvalue()).decode()
310
+
311
+ def __encode_video(self, video_path: str) -> Optional[str]:
312
+ thumb = Formatter.extract_first_video_frame(video_path)
313
+ return self.__encode_image(thumb) if thumb is not None else None
314
+
315
+ def __encode_document(self, doc_path: str) -> Optional[str]:
316
+ thumb = Formatter.make_document_thumbnail(doc_path)
317
+ return self.__encode_image(thumb) if thumb is not None else None
318
+
210
319
 
211
320
  class TableRestorer:
212
321
  """
@@ -63,10 +63,10 @@ class Formatter:
63
63
  """
64
64
  Escapes special characters in `val`, and abbreviates `val` if its length exceeds `_STRING_MAX_LEN`.
65
65
  """
66
- return cls.__escape(cls.__abbreviate(val, cls.__STRING_MAX_LEN))
66
+ return cls.__escape(cls.abbreviate(val))
67
67
 
68
68
  @classmethod
69
- def __abbreviate(cls, val: str, max_len: int) -> str:
69
+ def abbreviate(cls, val: str, max_len: int = __STRING_MAX_LEN) -> str:
70
70
  if len(val) > max_len:
71
71
  edgeitems = (max_len - len(cls.__STRING_SEP)) // 2
72
72
  return f'{val[:edgeitems]}{cls.__STRING_SEP}{val[-edgeitems:]}'
@@ -94,41 +94,45 @@ class Formatter:
94
94
  )
95
95
 
96
96
  @classmethod
97
- def format_json(cls, val: Any) -> str:
97
+ def format_json(cls, val: Any, escape_strings: bool = True) -> str:
98
98
  if isinstance(val, str):
99
99
  # JSON-like formatting will be applied to strings that appear nested within a list or dict
100
100
  # (quote the string; escape any quotes inside the string; shorter abbreviations).
101
101
  # However, if the string appears in top-level position (i.e., the entire JSON value is a
102
102
  # string), then we format it like an ordinary string.
103
- return cls.format_string(val)
103
+ return cls.format_string(val) if escape_strings else cls.abbreviate(val)
104
104
  # In all other cases, dump the JSON struct recursively.
105
- return cls.__format_json_rec(val)
105
+ return cls.__format_json_rec(val, escape_strings)
106
106
 
107
107
  @classmethod
108
- def __format_json_rec(cls, val: Any) -> str:
108
+ def __format_json_rec(cls, val: Any, escape_strings: bool) -> str:
109
109
  if isinstance(val, str):
110
- return cls.__escape(json.dumps(cls.__abbreviate(val, cls.__NESTED_STRING_MAX_LEN)))
110
+ formatted = json.dumps(cls.abbreviate(val, cls.__NESTED_STRING_MAX_LEN))
111
+ return cls.__escape(formatted) if escape_strings else formatted
111
112
  if isinstance(val, float):
112
113
  return cls.format_float(val)
113
114
  if isinstance(val, np.ndarray):
114
115
  return cls.format_array(val)
115
116
  if isinstance(val, list):
116
117
  if len(val) < cls.__LIST_THRESHOLD:
117
- components = [cls.__format_json_rec(x) for x in val]
118
+ components = [cls.__format_json_rec(x, escape_strings) for x in val]
118
119
  else:
119
- components = [cls.__format_json_rec(x) for x in val[: cls.__LIST_EDGEITEMS]]
120
+ components = [cls.__format_json_rec(x, escape_strings) for x in val[: cls.__LIST_EDGEITEMS]]
120
121
  components.append('...')
121
- components.extend(cls.__format_json_rec(x) for x in val[-cls.__LIST_EDGEITEMS :])
122
+ components.extend(cls.__format_json_rec(x, escape_strings) for x in val[-cls.__LIST_EDGEITEMS :])
122
123
  return '[' + ', '.join(components) + ']'
123
124
  if isinstance(val, dict):
124
- kv_pairs = (f'{cls.__format_json_rec(k)}: {cls.__format_json_rec(v)}' for k, v in val.items())
125
+ kv_pairs = (
126
+ f'{cls.__format_json_rec(k, escape_strings)}: {cls.__format_json_rec(v, escape_strings)}'
127
+ for k, v in val.items()
128
+ )
125
129
  return '{' + ', '.join(kv_pairs) + '}'
126
130
 
127
131
  # Everything else
128
132
  try:
129
133
  return json.dumps(val)
130
134
  except TypeError: # Not JSON serializable
131
- return str(val)
135
+ return cls.__escape(str(val))
132
136
 
133
137
  def format_img(self, img: Image.Image) -> str:
134
138
  """
@@ -152,22 +156,19 @@ class Formatter:
152
156
  """
153
157
 
154
158
  def format_video(self, file_path: str) -> str:
155
- thumb_tag = ''
156
159
  # Attempt to extract the first frame of the video to use as a thumbnail,
157
160
  # so that the notebook can be exported as HTML and viewed in contexts where
158
161
  # the video itself is not accessible.
159
162
  # TODO(aaron-siegel): If the video is backed by a concrete external URL,
160
163
  # should we link to that instead?
161
- with av.open(file_path) as container:
162
- try:
163
- thumb = next(container.decode(video=0)).to_image()
164
- assert isinstance(thumb, Image.Image)
165
- with io.BytesIO() as buffer:
166
- thumb.save(buffer, 'jpeg')
167
- thumb_base64 = base64.b64encode(buffer.getvalue()).decode()
168
- thumb_tag = f'poster="data:image/jpeg;base64,{thumb_base64}"'
169
- except Exception:
170
- pass
164
+ thumb = self.extract_first_video_frame(file_path)
165
+ if thumb is None:
166
+ thumb_tag = ''
167
+ else:
168
+ with io.BytesIO() as buffer:
169
+ thumb.save(buffer, 'jpeg')
170
+ thumb_base64 = base64.b64encode(buffer.getvalue()).decode()
171
+ thumb_tag = f'poster="data:image/jpeg;base64,{thumb_base64}"'
171
172
  if self.__num_rows > 1:
172
173
  width = 320
173
174
  elif self.__num_cols > 1:
@@ -182,6 +183,16 @@ class Formatter:
182
183
  </div>
183
184
  """
184
185
 
186
+ @classmethod
187
+ def extract_first_video_frame(cls, file_path: str) -> Optional[Image.Image]:
188
+ with av.open(file_path) as container:
189
+ try:
190
+ img = next(container.decode(video=0)).to_image()
191
+ assert isinstance(img, Image.Image)
192
+ return img
193
+ except Exception:
194
+ return None
195
+
185
196
  def format_audio(self, file_path: str) -> str:
186
197
  return f"""
187
198
  <div class="pxt_audio">
@@ -191,29 +202,18 @@ class Formatter:
191
202
  </div>
192
203
  """
193
204
 
194
- def format_document(self, file_path: str) -> str:
195
- max_width = max_height = 320
205
+ def format_document(self, file_path: str, max_width: int = 320, max_height: int = 320) -> str:
196
206
  # by default, file path will be shown as a link
197
207
  inner_element = file_path
198
208
  inner_element = html.escape(inner_element)
199
- # try generating a thumbnail for different types and use that if successful
200
- if file_path.lower().endswith('.pdf'):
201
- try:
202
- import fitz # type: ignore[import-untyped]
203
209
 
204
- doc = fitz.open(file_path)
205
- p = doc.get_page_pixmap(0)
206
- while p.width > max_width or p.height > max_height:
207
- # shrink(1) will halve each dimension
208
- p.shrink(1)
209
- data = p.tobytes(output='jpeg')
210
- thumb_base64 = base64.b64encode(data).decode()
211
- img_src = f'data:image/jpeg;base64,{thumb_base64}'
212
- inner_element = f"""
213
- <img style="object-fit: contain; border: 1px solid black;" src="{img_src}" />
214
- """
215
- except Exception:
216
- logging.warning(f'Failed to produce PDF thumbnail {file_path}. Make sure you have PyMuPDF installed.')
210
+ thumb = self.make_document_thumbnail(file_path, max_width, max_height)
211
+ if thumb is not None:
212
+ with io.BytesIO() as buffer:
213
+ thumb.save(buffer, 'webp')
214
+ thumb_base64 = base64.b64encode(buffer.getvalue()).decode()
215
+ thumb_tag = f'data:image/webp;base64,{thumb_base64}'
216
+ inner_element = f'<img style="object-fit: contain; border: 1px solid black;" src="{thumb_tag}" />'
217
217
 
218
218
  return f"""
219
219
  <div class="pxt_document" style="width:{max_width}px;">
@@ -223,6 +223,28 @@ class Formatter:
223
223
  </div>
224
224
  """
225
225
 
226
+ @classmethod
227
+ def make_document_thumbnail(
228
+ cls, file_path: str, max_width: int = 320, max_height: int = 320
229
+ ) -> Optional[Image.Image]:
230
+ """
231
+ Returns a thumbnail image of a document.
232
+ """
233
+ if file_path.lower().endswith('.pdf'):
234
+ try:
235
+ import fitz # type: ignore[import-untyped]
236
+
237
+ doc = fitz.open(file_path)
238
+ pixmap = doc.get_page_pixmap(0)
239
+ while pixmap.width > max_width or pixmap.height > max_height:
240
+ # shrink(1) will halve each dimension
241
+ pixmap.shrink(1)
242
+ return pixmap.pil_image()
243
+ except Exception:
244
+ logging.warning(f'Failed to produce PDF thumbnail {file_path}. Make sure you have PyMuPDF installed.')
245
+
246
+ return None
247
+
226
248
  @classmethod
227
249
  def __create_source_tag(cls, http_address: str, file_path: str) -> str:
228
250
  src_url = get_file_uri(http_address, file_path)
@@ -0,0 +1,25 @@
1
+ import sqlalchemy as sql
2
+
3
+ from pixeltable.func.udf import udf
4
+
5
+
6
+ @udf
7
+ def sample_key(seed: int, *key_fields: int) -> str:
8
+ """
9
+ Create a sample key from the given seed and key fields.
10
+
11
+ Args:
12
+ seed: The seed value.
13
+ rowids: The rowids to include in the sample key.
14
+
15
+ Returns:
16
+ A string key for each row
17
+ """
18
+ raise NotImplementedError('SampleKey creation is not implemented in python.')
19
+
20
+
21
+ @sample_key.to_sql
22
+ def _(seed: sql.ColumnElement, *key_fields: sql.ColumnElement) -> sql.ColumnElement:
23
+ from pixeltable.exec.sql_node import SqlSampleNode
24
+
25
+ return SqlSampleNode.key_sql_expr(seed, key_fields)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pixeltable
3
- Version: 0.4.0rc1
3
+ Version: 0.4.0rc3
4
4
  Summary: AI Data Infrastructure: Declarative, Multimodal, and Incremental
5
5
  License: Apache-2.0
6
6
  Keywords: data-science,machine-learning,database,ai,computer-vision,chatbot,ml,artificial-intelligence,feature-engineering,multimodal,mlops,feature-store,vector-database,llm,genai
@@ -36,6 +36,7 @@ Requires-Dist: numpy (>=1.25)
36
36
  Requires-Dist: pandas (>=2.0,<3.0)
37
37
  Requires-Dist: pgvector (>=0.2.1)
38
38
  Requires-Dist: pillow (>=9.3.0)
39
+ Requires-Dist: pillow-heif (>=0.15.0)
39
40
  Requires-Dist: pixeltable-pgserver (==0.3.1)
40
41
  Requires-Dist: psutil (>=5.9.5)
41
42
  Requires-Dist: psycopg[binary] (>=3.1.18)
@@ -1,7 +1,7 @@
1
1
  pixeltable/__init__.py,sha256=-uXHuiXH98kAlCupUTPbkBh4ToZgxcYUOk7-c9hqCC8,1439
2
- pixeltable/__version__.py,sha256=8n05k74lzCnT5buUnz2d9g9yaA6gdHgtEi-A_Z20pO4,120
2
+ pixeltable/__version__.py,sha256=l1gVhW4YjeNouBt4ti5Rxsd1ETc8Ls5nKRC8aMceXrM,120
3
3
  pixeltable/catalog/__init__.py,sha256=rQmjveID4bk6NI4Ql09lGsZ0K0HVE2l1yqKAveipHzc,558
4
- pixeltable/catalog/catalog.py,sha256=mMivgHA6ru3HGZAiEfiQyP2yJEI7-LFhkGg_PlFSewc,59246
4
+ pixeltable/catalog/catalog.py,sha256=ExHm2bbAs_4-T6zq3ow2fQ5a9Zja6G3WzHoo3Qk0X40,59399
5
5
  pixeltable/catalog/column.py,sha256=v3SE6CQs_ZXTDkBeiJ7gu9sxBJD-6EbkjsB1TZvLSJI,11280
6
6
  pixeltable/catalog/dir.py,sha256=HFemOf67Nfw13EOpQsR_UgzP2L1w4LDfw2009DrSK0Y,2063
7
7
  pixeltable/catalog/globals.py,sha256=7fNUs67D18PZ1ZajcGz7KQOV6tuXEcYLSrePzgmDkRw,4036
@@ -9,16 +9,16 @@ pixeltable/catalog/insertable_table.py,sha256=tl3tvMVPzi9A_SRARV6660NQnt8w09hNbO
9
9
  pixeltable/catalog/named_function.py,sha256=vZ-j7P4HugWh9OmUzBMwyRYvO3tQn9jWyJz_1stPavU,1210
10
10
  pixeltable/catalog/path.py,sha256=gk8TIlO_7Jpji5mAN0dUNvHmvU0uneTHeB_qCTWnszQ,2529
11
11
  pixeltable/catalog/schema_object.py,sha256=B9Am6W1bWnAMFZ4qFTfYw6g8F0-q_2aezBB1bUHL_RY,1812
12
- pixeltable/catalog/table.py,sha256=iE4PAulsxnlCjmSOMxVFD2mXNEch7owty4tbS-IfOHk,68084
13
- pixeltable/catalog/table_version.py,sha256=FqVuZdAbp7Bo0dt7zQGHtwTOUmS2qAiEtHrMQSOxqek,66289
12
+ pixeltable/catalog/table.py,sha256=JUiQPQP33486KiPVio8aBTibNGUYwulDgU1UfGDaprU,68609
13
+ pixeltable/catalog/table_version.py,sha256=1dq2uq-I2E4d2SkBMA5MQFqkutPQCi-7HlNo24Trrjw,66775
14
14
  pixeltable/catalog/table_version_handle.py,sha256=E0iPIp2PUbE7r3WZzerBJ7fgKX3vaTWPnn6cOwKLF-A,2581
15
15
  pixeltable/catalog/table_version_path.py,sha256=2JEprCdDzCfr9dPxlMhsQ80jYqJ0-8uBNgNXt3D-bao,9042
16
- pixeltable/catalog/view.py,sha256=jlLyu71LMmz33WnfnXX3jANRJOtGM6SDifppApI0yJI,13585
16
+ pixeltable/catalog/view.py,sha256=1UN-k0Ck0IWyy2Ae5b520L08GAfQ17L4FaZtS2bQ-TA,14786
17
17
  pixeltable/config.py,sha256=gnRI4G9GE7mQJDcMcn8JsEzYk8oKVfHB-BwoLRWnRDo,3971
18
- pixeltable/dataframe.py,sha256=U8QRC74phOtSnVMI9uxTZR_GB_GKUQLe0_Md7e3Rf80,51851
19
- pixeltable/env.py,sha256=1t5ZBrLCLSPaz0nD_sCQvvfB6tjBppVI9Io4iJtdmNE,36024
18
+ pixeltable/dataframe.py,sha256=L1lNcfHtxxRw_b8kgkmvcuYXQyniAzwLnI4ww79P5B4,60393
19
+ pixeltable/env.py,sha256=BtBxkKgU3wi6_0rfor3k3Kx6SF660JH24sWprbBzB8w,36132
20
20
  pixeltable/exceptions.py,sha256=eI2f4oXqv678_fDOxeYOTPE_EF1CMX3pwCqtJvN8i7s,926
21
- pixeltable/exec/__init__.py,sha256=m4AF2kzFtsTRUevupgWs8er0oJQisCR9ROW7ZJlL3dw,509
21
+ pixeltable/exec/__init__.py,sha256=hQvj4ra4ubxu94qyuCBTHKsuYGzundkTTluOTIb5Bx8,524
22
22
  pixeltable/exec/aggregation_node.py,sha256=HqzISO1nv7_DFyqjZLRkjtbDJl9fIEto1i6Kh5ru8vA,4498
23
23
  pixeltable/exec/cache_prefetch_node.py,sha256=GOa70eJDFY3FQV3VvJOrUVI8LFvro-r-V6sh3w-eJAc,12130
24
24
  pixeltable/exec/component_iteration_node.py,sha256=FZszWHrzsjHxCbUTwXtJIlgQqgYtvKZB6QWiDGkfIbs,4757
@@ -26,14 +26,14 @@ pixeltable/exec/data_row_batch.py,sha256=EAB15JRhXbWIe91x1J5N5lFiMXzjB8NGTFjZsBD
26
26
  pixeltable/exec/exec_context.py,sha256=jKeLStfkjwCKKAooC-7a7qZUnZU5O0_JQhanhVerV9c,984
27
27
  pixeltable/exec/exec_node.py,sha256=WIN1sBEBNS7TlBk5QpHsDUCZUUdcvs6Os_Bxq2HoWdo,4077
28
28
  pixeltable/exec/expr_eval/__init__.py,sha256=sQThSEByK_DLfB-_-18RFhpARx49cSXYEkpCDyi0vQI,61
29
- pixeltable/exec/expr_eval/evaluators.py,sha256=AJkuleKhEz_8W6F3dcjTbWyKfv4IzpTh3cvQ3--OkRg,16865
29
+ pixeltable/exec/expr_eval/evaluators.py,sha256=-6s_y29Wh8p35SVKkXtnA0NkzcHVw1Z8PgHGiFrMsqs,17135
30
30
  pixeltable/exec/expr_eval/expr_eval_node.py,sha256=ABkC2yAcMSCtQ7AvNAn6rfj3AMscVzezttKSs1ExNhw,18972
31
31
  pixeltable/exec/expr_eval/globals.py,sha256=fFrj2O53TgHDfVF8dgnyn1fPLi4ZHQuylewf5aHMwYk,7752
32
32
  pixeltable/exec/expr_eval/row_buffer.py,sha256=YY0thdlMNNReEOTyPp36xKPeMeXSZ0VrI9bJsXgo7sU,2744
33
33
  pixeltable/exec/expr_eval/schedulers.py,sha256=tAvCQKa1q0x7y7cdnGcTGbeku8QcoKH1GkgSm8ktOnM,17000
34
34
  pixeltable/exec/in_memory_data_node.py,sha256=vmxD2Jwn15Wjkf_3wufr35SPjb60H_I4zpUKaO1Zo_s,3592
35
35
  pixeltable/exec/row_update_node.py,sha256=zU0eSyn81-vRrjAMOadRqU8luTshnPUtIbS7npyLBKY,2798
36
- pixeltable/exec/sql_node.py,sha256=SBnmFvt1Iit5Sx1-iUqvtwyHNBdZPHlikhlrUtFnncs,20098
36
+ pixeltable/exec/sql_node.py,sha256=MM9wD0AMXh11qJayhMgieCJ36hww-ym1p7kfS2y9-wM,26540
37
37
  pixeltable/exprs/__init__.py,sha256=AxSMjKNavCT9F6vBaNR-nwX2iupAI5hbMb5hEj65Tfk,1096
38
38
  pixeltable/exprs/arithmetic_expr.py,sha256=sZPao0qdFWbrDx0eiAVxw1wGHJXZ5ZoCpQaScysBldE,7333
39
39
  pixeltable/exprs/array_slice.py,sha256=8Zv0E2RghdJi1Mbk0kKtOz2ccGQuXwLLb6R9v1jk7hA,2180
@@ -41,8 +41,8 @@ pixeltable/exprs/column_property_ref.py,sha256=28UcsrMIoXmMy6DAgJ0GP6Vw4sYwXcspV
41
41
  pixeltable/exprs/column_ref.py,sha256=LljuQiNYh6dQa_EV57ylPfNkQD-lfHBFTGDY8WlnnfY,14942
42
42
  pixeltable/exprs/comparison.py,sha256=lgaRx000ZaNH10A4hrtsi5XoZKE-CNEONGMi7jxJfcM,5133
43
43
  pixeltable/exprs/compound_predicate.py,sha256=vJVRVueAmaKnjiHCLWyh8wHgktzzK0DVqbOIQJgTjF8,3801
44
- pixeltable/exprs/data_row.py,sha256=y16wVbp_ISNmMUP18PtX5vFrc4zxCiV3f9jCoReKl6I,11396
45
- pixeltable/exprs/expr.py,sha256=JABPT8dGISMq_ciG67GPdX00nKTrJwQ1DQhxSRqkC4A,35602
44
+ pixeltable/exprs/data_row.py,sha256=8p0eWunvg_2ZH-e7Gtz_woxBAoizaCV2QtN87Is8_ys,11484
45
+ pixeltable/exprs/expr.py,sha256=YFPL81s9N1_Obl15zpk_yYUvKqVoBT8fpAXhkYqgHLs,36000
46
46
  pixeltable/exprs/expr_dict.py,sha256=2ZeZ0eACx3VrRNEOjipuT5WxOIzjXQ_DSip8NTH0KRo,1584
47
47
  pixeltable/exprs/expr_set.py,sha256=OlRTbHAAYH2fOEs1HE-8DIu7Z247xVfoT_9Y58GZoOQ,2559
48
48
  pixeltable/exprs/function_call.py,sha256=_PxrEACVyiihdQdmTiiSv5WkZfOXSQFcGO18wPueM_Y,21989
@@ -52,7 +52,7 @@ pixeltable/exprs/inline_expr.py,sha256=XYVKKXZN9BtHN5qlvZna-mgdOlot6WcmPu5usRBYe
52
52
  pixeltable/exprs/is_null.py,sha256=NfA_485hfT69pWyY6u8BhykDUkz5k91AH93azGu6lCg,1087
53
53
  pixeltable/exprs/json_mapper.py,sha256=bJSB39sZgpN9KS0RReDnUhTCwg-4Y4cgXXaFNy3o3wU,7035
54
54
  pixeltable/exprs/json_path.py,sha256=sFuDjfz8_rlea4TKd68CS4pQTUiLDi68YwsgcQRHffI,7162
55
- pixeltable/exprs/literal.py,sha256=kLAqc05uRHTN1IGAmRUNRkglo9CYualF7zW_U7c2pwU,4846
55
+ pixeltable/exprs/literal.py,sha256=OCJL_pw_WKqx3bXMEwL6yNaKVAKDtGRzSZUFwucRxZI,4860
56
56
  pixeltable/exprs/method_ref.py,sha256=NNhJTGo7luZLh8EJdFIZAax9LiiqqDCEK1AwPmHip0w,2642
57
57
  pixeltable/exprs/object_ref.py,sha256=idYFcT27jv0BjtJT3paL37xDrZZc35_3eCJyQOIqdZU,1999
58
58
  pixeltable/exprs/row_builder.py,sha256=LL8q_8AthTqH8duWqKwdaS8DlvUsC8chclzQRR4MJAE,21150
@@ -75,34 +75,34 @@ pixeltable/func/function_registry.py,sha256=7AQ1bdF2DJbTRn9xx6s5cC_VHtCBXGt_GyJJ
75
75
  pixeltable/func/globals.py,sha256=5Wo4GPxYgHRRk5nvV0h_lAthKSalxKvj5n1p-uMPR0U,1501
76
76
  pixeltable/func/query_template_function.py,sha256=25nvgadWgk16BU7X5uI7PvKfkoluJSuOqsAcY5AN-Yw,7915
77
77
  pixeltable/func/signature.py,sha256=0PI6xdhLgwy9-GMkzkm7GlsBnsNMiS9aoNI9LWXwvN0,13700
78
- pixeltable/func/tools.py,sha256=DIfkOEj9Bp797Ew014_4YJePoUW40fQ6mvbCeg0FBR0,5721
78
+ pixeltable/func/tools.py,sha256=bmHnnd9lXkQ8sYHp5RSMF56NimSTE3uhG2xbIxs4Np4,5726
79
79
  pixeltable/func/udf.py,sha256=qQfaX1O3ZhUvSgiNnitW7nRKnZFJ5yu_Fj9ioqQgjqg,13219
80
80
  pixeltable/functions/__init__.py,sha256=x_ZodeEtayD2XDjlDZE4L_QTzajF6riftIc5P4ZjEiY,578
81
- pixeltable/functions/anthropic.py,sha256=oTiXMfy3MupBInGRFEVkp-pHu06gF1ezJjEM2ypyvXw,9323
81
+ pixeltable/functions/anthropic.py,sha256=G2E0sH5vP933eZZxhz1tOByy5cg6N2XPvhSqIBzqufo,8782
82
82
  pixeltable/functions/audio.py,sha256=7bsm4igQEW7RYSrSevwqaUOqyEnvBbPbJ8c-VknDl1E,657
83
83
  pixeltable/functions/bedrock.py,sha256=lTCFHjYunF3minBGWcjXR90yJ8resFjXr4niyKhfxms,4217
84
84
  pixeltable/functions/date.py,sha256=WUwqyrOWB8A00cTNEd6Vd7anQZo40_-7EWhpfpI-P6c,5323
85
- pixeltable/functions/deepseek.py,sha256=KYIa-UJJUTOt9cCfmP6k6nM4MpKm1MBU8F-jWk3CycY,3827
86
- pixeltable/functions/fireworks.py,sha256=k0vUXxeeNYWfL_tdLgF9c-vOilr0g2tTeLkAL9SJ6ws,4972
87
- pixeltable/functions/gemini.py,sha256=zWPsvtq0mPFBC_-4N7NDuhTYZfAzRMmZa9S4GFjIpLg,8328
85
+ pixeltable/functions/deepseek.py,sha256=IAo2e_DhkM0A5NrskxuPQUGYzIYAl4do_mdO1Qc3PeY,3338
86
+ pixeltable/functions/fireworks.py,sha256=q7eWlYfiWbA0d9r3CB_NAe1fw3q-Z7qsw2gyGJNgWLQ,4786
87
+ pixeltable/functions/gemini.py,sha256=ZsbySkoMdOgZEUfFUccDbIdrbLb6DGRxzD88fHW-cRI,8317
88
88
  pixeltable/functions/globals.py,sha256=ZXBV2LPXT2-yQYHHE7q8N1WdAr0WxiIO1ax0qwxhmK8,5118
89
89
  pixeltable/functions/huggingface.py,sha256=KM1OH0Jt6XWF2jfpHb6rGhi1mV-AQNYAsHAyQfzW4qw,20560
90
90
  pixeltable/functions/image.py,sha256=IKXljMma-uU88efptC3F4aywau7DYcD-Nqd3YpmRNRw,13971
91
91
  pixeltable/functions/json.py,sha256=d7-AvwytUQtQYF_JnWJkptT_Yq0NgMpWfVk-m3U6qTY,807
92
- pixeltable/functions/llama_cpp.py,sha256=uf7WSZIhKDa492snnQv5ojGVLNdBWvuw0Ou3Mch1c_I,3874
92
+ pixeltable/functions/llama_cpp.py,sha256=1QB4vQ7J4Za1mL93bRIBXgokNtpzzYr_QU6KF27i9xo,3919
93
93
  pixeltable/functions/math.py,sha256=eZEFjXxNHDHjcCsOMhzfNbJthTsmtNxtSFV8AEeRIfM,4979
94
- pixeltable/functions/mistralai.py,sha256=yZge5T385RoiFGXEZ6OhwWHj0JnsZ8tN8Jb3VkfDmXc,6274
95
- pixeltable/functions/ollama.py,sha256=AmkP532HwWeTyWkTnHm_hIk0CFjzV5MwCCPnM9Kb7KM,4231
96
- pixeltable/functions/openai.py,sha256=aDh1L2mBbSlrM8c1Rbh2QsCnmBESItLqzZ-frdgb05k,29259
94
+ pixeltable/functions/mistralai.py,sha256=PTXQegC2LO5Pw0zXBO_SVV7I2c5qBvqVVgfm_mK1ir0,5845
95
+ pixeltable/functions/ollama.py,sha256=4-6h9Foq_7Ut7JtEHGkeg1KbuKaFywSuMrKiw0xAyCA,4231
96
+ pixeltable/functions/openai.py,sha256=kzi8HApD971O54Xl82G0jI7n0E2ui476kV1wAKObx88,27768
97
97
  pixeltable/functions/replicate.py,sha256=SLMPNi44QMa16TVTImZRkNMXXyRZ0mmpnK6P5uXQE0k,2467
98
98
  pixeltable/functions/string.py,sha256=LdBNOna5PUSPmM5VlJ_qhmwzyFhumW0k6Dvx2rXSZtc,25356
99
99
  pixeltable/functions/timestamp.py,sha256=0zp4urJagCcNLfJE0ltTCft-J9qs2C716TmRngKYaa0,9171
100
- pixeltable/functions/together.py,sha256=ufg0RehEoQEqBy9EHSKY4N3ZNT5O__cwDS0Ll467eLk,10014
100
+ pixeltable/functions/together.py,sha256=A8J19BXywyWQ6a2_n05-8uIG5jquOBGqPmW3mb-NrIc,8842
101
101
  pixeltable/functions/util.py,sha256=lVya13gcao8T34OGX7zy1cglQPNwaBbSBw57bVPyHNs,745
102
102
  pixeltable/functions/video.py,sha256=jS4YhMofD448YhGtI6ZXBAkeGw_AYYQTN0AbgHh_hok,6933
103
103
  pixeltable/functions/vision.py,sha256=_a0wY3akkVhWnnxlq__1VzSLylytlNadpNOOPOwSfLk,15393
104
104
  pixeltable/functions/whisper.py,sha256=c9E6trhc2UcShVaGaEBCUEpArke1ql3MV5We0qSgmuU,2960
105
- pixeltable/globals.py,sha256=IBeT0bJ4VxfNcmPkjyplZMYyM3bZ9PPFOPIq25GiZE4,32062
105
+ pixeltable/globals.py,sha256=cM3uKvDJWIs1I9A8rzXaZsKCDSaLBh7KVb1lakQqGzk,32377
106
106
  pixeltable/index/__init__.py,sha256=97aFuxiP_oz1ldn5iq8IWApkOV8XG6ZIBW5-9rkS0vM,122
107
107
  pixeltable/index/base.py,sha256=200s7v3Zy810bRlbSAYzxxaEjVssl6r8esTHiSvWRwQ,1704
108
108
  pixeltable/index/btree.py,sha256=8B06D67ay0DFUtEBC5q4bLjxMq7ILpKyyoLAiSaamzA,2503
@@ -125,7 +125,7 @@ pixeltable/iterators/document.py,sha256=wJYSnzusJFaxipv5y0uQw-surN9fFz0Aq-s7w_l_
125
125
  pixeltable/iterators/image.py,sha256=nWm-03CxNvHRdTr8U6PvWEnEiquqIQNG5rB-3Y44Mm4,3440
126
126
  pixeltable/iterators/string.py,sha256=URj5edWp-CsorjN_8nnfWGvtIFs_Zh4VPm6htlJbFkU,1257
127
127
  pixeltable/iterators/video.py,sha256=L5S1YPmT_zM11vW9fK6d5nQpUvHVewQWmfDmy4BD45E,9134
128
- pixeltable/metadata/__init__.py,sha256=gr9PE_iZ1Cze8h2Pj03c1ItShqUq7IxCwVnkV18DZbE,2607
128
+ pixeltable/metadata/__init__.py,sha256=fZ3HaB-L8lHJdrtmKqfIJJlvYG0CqzzxKFRrh9IWoa0,3154
129
129
  pixeltable/metadata/converters/convert_10.py,sha256=myYIo1DyccnsQUxDKG6mafnU5ge_EhZpHg_pesKBoK4,708
130
130
  pixeltable/metadata/converters/convert_12.py,sha256=Ci-qyZW1gqci-8wnjeOB5afdq7KTuN-hVSV9OqSPx8g,162
131
131
  pixeltable/metadata/converters/convert_13.py,sha256=B-_EkL0pSl1mAiv6DymeUAyBQUcYcV1qDdNz3Q359kc,1369
@@ -151,13 +151,14 @@ pixeltable/metadata/converters/convert_32.py,sha256=YENfuQ_mqhnZWrvHJffaGEqd1IwS
151
151
  pixeltable/metadata/converters/convert_33.py,sha256=ZZV3FTyyouBM1eNymXxfHV-Oqmgu2s0KNP6AG3zc5eM,574
152
152
  pixeltable/metadata/converters/convert_34.py,sha256=1hi7m49CMzHRD25rrePS-SMCsZ-4opzDhY0JqU8Jzw4,690
153
153
  pixeltable/metadata/converters/convert_35.py,sha256=c88qft0RFQbdFIE_PZRHMjeku1r5HCLN7wrvndQSXdI,266
154
+ pixeltable/metadata/converters/convert_36.py,sha256=g1rhZhAYfZpAwUgE3D1aipIR4RNvikhbKcrnBJzm0wM,1215
154
155
  pixeltable/metadata/converters/util.py,sha256=95pfg9amEOmhho32PIbNYnqagVIN9adIcLXxB6zSYDY,7527
155
- pixeltable/metadata/notes.py,sha256=mCRyBvHNMsQ1fmORGcVIuiPwy7ya7vqbF8jmiSaCMNg,1347
156
- pixeltable/metadata/schema.py,sha256=JSbZEwEzFFAV8__i5VtrkfhxgedlFI76rxk3_esNMF8,11382
157
- pixeltable/plan.py,sha256=0xEHwqIUsgmSlLbYfmkyHuQNiD6lOumvx4UiNIk-KUw,43639
156
+ pixeltable/metadata/notes.py,sha256=7HKk4yQLh8zaTVgv4pGXvpn3PoF5x7OFO8YSog5TLHI,1408
157
+ pixeltable/metadata/schema.py,sha256=5r-loBIyYiZdkbszrLdn0XktOgDh96UVp_GScmm-14g,11489
158
+ pixeltable/plan.py,sha256=bL6B32J63P1QtGjLhwwcfbh2SrSEeuyb1Zh6txdKQ6Q,52136
158
159
  pixeltable/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
159
160
  pixeltable/share/__init__.py,sha256=AtR4nS6YkfkFRkXA-zZXFTK5pSQjHry8MnxdVLUk5SA,68
160
- pixeltable/share/packager.py,sha256=SyM-mzKoHLhgahFmJPkPSbBd1553nqs5FZnVTn4WNsg,27689
161
+ pixeltable/share/packager.py,sha256=udwsorQDWX0N9eHcPHlT5xyAeUxGvT7DBnsFuq8PALM,32149
161
162
  pixeltable/share/publish.py,sha256=U6PzOUYiZaPu-sVNjh2nN8qzY2-uMsYeTwQCCuGk7Jg,6537
162
163
  pixeltable/store.py,sha256=2tfMgJNVVbGShgAKghGAIFMZ-ViJHE7N9kWd2ugbi2A,24691
163
164
  pixeltable/type_system.py,sha256=DSrof2NgKhBzvt7pbDNrGlZ3rkkDJ7MQsQ9rqk9N9pA,53988
@@ -172,16 +173,17 @@ pixeltable/utils/description_helper.py,sha256=acibNm36wkZG7h6k8gjcypTD_PVV2SL7Yg
172
173
  pixeltable/utils/documents.py,sha256=x3UHU7eykibyA3eVkSrCK1CQoaid228vp96WUEESssU,3105
173
174
  pixeltable/utils/exception_handler.py,sha256=yrTAtUJEOhldps_k6aRLEf5yQ8gYGhl9c6ewYNC4Qfc,2476
174
175
  pixeltable/utils/filecache.py,sha256=8RZZiEkD4awZpR-mn7OhoZPc6_JlPUNSBnMU8BcEAv4,10864
175
- pixeltable/utils/formatter.py,sha256=_pYQOhBh2dZBeCTUKuWaIzm7JRWeMepMZwSd5KTv-tw,9220
176
+ pixeltable/utils/formatter.py,sha256=tbMxE9rBw6wdKUnJhNZ8h9uAF8dZKcihQ2KesqAag9A,10096
176
177
  pixeltable/utils/http_server.py,sha256=B5iQ1s_VuwsVC7pUm1joGjLZqaluV8_RfFiU8V1FuG8,2453
177
178
  pixeltable/utils/iceberg.py,sha256=L_s9G9NMIGMQdRHtNkks6ntTVW4DKKAw97R9gRmtw5s,553
178
179
  pixeltable/utils/media_store.py,sha256=Dhsnj1ZPRSX0iyGOu4JU4pC3fvSBd7sQpruVHqzKm7A,3089
179
180
  pixeltable/utils/pytorch.py,sha256=564VHRdDHwD9h0v5lBHEDTJ8c6zx8wuzWYx8ZYjBxlI,3621
180
181
  pixeltable/utils/s3.py,sha256=pxip2MlCqd2Qon2dzJXzfxvwtZyc-BAsjAnLL4J_OXY,587
182
+ pixeltable/utils/sample.py,sha256=Pj8oSZw0WsdASD1BpTtKiWP4cwef7KQqVAfIFKlJNxA,643
181
183
  pixeltable/utils/sql.py,sha256=Sa4Lh-VGe8GToU5W7DRiWf2lMl9B6saPqemiT0ZdHEc,806
182
184
  pixeltable/utils/transactional_directory.py,sha256=OFKmu90oP7KwBAljwjnzP_w8euGdAXob3y4Nx9SCNHA,1357
183
- pixeltable-0.4.0rc1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
184
- pixeltable-0.4.0rc1.dist-info/METADATA,sha256=uD_AiJ5nJXk4YoVxcjAulmt9qsJGRruGMZfjdX_264Y,20542
185
- pixeltable-0.4.0rc1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
186
- pixeltable-0.4.0rc1.dist-info/entry_points.txt,sha256=ToOd-pRgG7AitEBgYoBCRRB4-KVDQ0pj_9T4a1LgwA4,97
187
- pixeltable-0.4.0rc1.dist-info/RECORD,,
185
+ pixeltable-0.4.0rc3.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
186
+ pixeltable-0.4.0rc3.dist-info/METADATA,sha256=iRhLy9JQXIsjwIOKQnvJBQCJuGfh_Xc56W3dcgWGs-A,20580
187
+ pixeltable-0.4.0rc3.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
188
+ pixeltable-0.4.0rc3.dist-info/entry_points.txt,sha256=ToOd-pRgG7AitEBgYoBCRRB4-KVDQ0pj_9T4a1LgwA4,97
189
+ pixeltable-0.4.0rc3.dist-info/RECORD,,