pixeltable 0.3.14__py3-none-any.whl → 0.5.7__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.
- pixeltable/__init__.py +42 -8
- pixeltable/{dataframe.py → _query.py} +470 -206
- pixeltable/_version.py +1 -0
- pixeltable/catalog/__init__.py +5 -4
- pixeltable/catalog/catalog.py +1785 -432
- pixeltable/catalog/column.py +190 -113
- pixeltable/catalog/dir.py +2 -4
- pixeltable/catalog/globals.py +19 -46
- pixeltable/catalog/insertable_table.py +191 -98
- pixeltable/catalog/path.py +63 -23
- pixeltable/catalog/schema_object.py +11 -15
- pixeltable/catalog/table.py +843 -436
- pixeltable/catalog/table_metadata.py +103 -0
- pixeltable/catalog/table_version.py +978 -657
- pixeltable/catalog/table_version_handle.py +72 -16
- pixeltable/catalog/table_version_path.py +112 -43
- pixeltable/catalog/tbl_ops.py +53 -0
- pixeltable/catalog/update_status.py +191 -0
- pixeltable/catalog/view.py +134 -90
- pixeltable/config.py +134 -22
- pixeltable/env.py +471 -157
- pixeltable/exceptions.py +6 -0
- pixeltable/exec/__init__.py +4 -1
- pixeltable/exec/aggregation_node.py +7 -8
- pixeltable/exec/cache_prefetch_node.py +83 -110
- pixeltable/exec/cell_materialization_node.py +268 -0
- pixeltable/exec/cell_reconstruction_node.py +168 -0
- pixeltable/exec/component_iteration_node.py +4 -3
- pixeltable/exec/data_row_batch.py +8 -65
- pixeltable/exec/exec_context.py +16 -4
- pixeltable/exec/exec_node.py +13 -36
- pixeltable/exec/expr_eval/evaluators.py +11 -7
- pixeltable/exec/expr_eval/expr_eval_node.py +27 -12
- pixeltable/exec/expr_eval/globals.py +8 -5
- pixeltable/exec/expr_eval/row_buffer.py +1 -2
- pixeltable/exec/expr_eval/schedulers.py +106 -56
- pixeltable/exec/globals.py +35 -0
- pixeltable/exec/in_memory_data_node.py +19 -19
- pixeltable/exec/object_store_save_node.py +293 -0
- pixeltable/exec/row_update_node.py +16 -9
- pixeltable/exec/sql_node.py +351 -84
- pixeltable/exprs/__init__.py +1 -1
- pixeltable/exprs/arithmetic_expr.py +27 -22
- pixeltable/exprs/array_slice.py +3 -3
- pixeltable/exprs/column_property_ref.py +36 -23
- pixeltable/exprs/column_ref.py +213 -89
- pixeltable/exprs/comparison.py +5 -5
- pixeltable/exprs/compound_predicate.py +5 -4
- pixeltable/exprs/data_row.py +164 -54
- pixeltable/exprs/expr.py +70 -44
- pixeltable/exprs/expr_dict.py +3 -3
- pixeltable/exprs/expr_set.py +17 -10
- pixeltable/exprs/function_call.py +100 -40
- pixeltable/exprs/globals.py +2 -2
- pixeltable/exprs/in_predicate.py +4 -4
- pixeltable/exprs/inline_expr.py +18 -32
- pixeltable/exprs/is_null.py +7 -3
- pixeltable/exprs/json_mapper.py +8 -8
- pixeltable/exprs/json_path.py +56 -22
- pixeltable/exprs/literal.py +27 -5
- pixeltable/exprs/method_ref.py +2 -2
- pixeltable/exprs/object_ref.py +2 -2
- pixeltable/exprs/row_builder.py +167 -67
- pixeltable/exprs/rowid_ref.py +25 -10
- pixeltable/exprs/similarity_expr.py +58 -40
- pixeltable/exprs/sql_element_cache.py +4 -4
- pixeltable/exprs/string_op.py +5 -5
- pixeltable/exprs/type_cast.py +3 -5
- pixeltable/func/__init__.py +1 -0
- pixeltable/func/aggregate_function.py +8 -8
- pixeltable/func/callable_function.py +9 -9
- pixeltable/func/expr_template_function.py +17 -11
- pixeltable/func/function.py +18 -20
- pixeltable/func/function_registry.py +6 -7
- pixeltable/func/globals.py +2 -3
- pixeltable/func/mcp.py +74 -0
- pixeltable/func/query_template_function.py +29 -27
- pixeltable/func/signature.py +46 -19
- pixeltable/func/tools.py +31 -13
- pixeltable/func/udf.py +18 -20
- pixeltable/functions/__init__.py +16 -0
- pixeltable/functions/anthropic.py +123 -77
- pixeltable/functions/audio.py +147 -10
- pixeltable/functions/bedrock.py +13 -6
- pixeltable/functions/date.py +7 -4
- pixeltable/functions/deepseek.py +35 -43
- pixeltable/functions/document.py +81 -0
- pixeltable/functions/fal.py +76 -0
- pixeltable/functions/fireworks.py +11 -20
- pixeltable/functions/gemini.py +195 -39
- pixeltable/functions/globals.py +142 -14
- pixeltable/functions/groq.py +108 -0
- pixeltable/functions/huggingface.py +1056 -24
- pixeltable/functions/image.py +115 -57
- pixeltable/functions/json.py +1 -1
- pixeltable/functions/llama_cpp.py +28 -13
- pixeltable/functions/math.py +67 -5
- pixeltable/functions/mistralai.py +18 -55
- pixeltable/functions/net.py +70 -0
- pixeltable/functions/ollama.py +20 -13
- pixeltable/functions/openai.py +240 -226
- pixeltable/functions/openrouter.py +143 -0
- pixeltable/functions/replicate.py +4 -4
- pixeltable/functions/reve.py +250 -0
- pixeltable/functions/string.py +239 -69
- pixeltable/functions/timestamp.py +16 -16
- pixeltable/functions/together.py +24 -84
- pixeltable/functions/twelvelabs.py +188 -0
- pixeltable/functions/util.py +6 -1
- pixeltable/functions/uuid.py +30 -0
- pixeltable/functions/video.py +1515 -107
- pixeltable/functions/vision.py +8 -8
- pixeltable/functions/voyageai.py +289 -0
- pixeltable/functions/whisper.py +16 -8
- pixeltable/functions/whisperx.py +179 -0
- pixeltable/{ext/functions → functions}/yolox.py +2 -4
- pixeltable/globals.py +362 -115
- pixeltable/index/base.py +17 -21
- pixeltable/index/btree.py +28 -22
- pixeltable/index/embedding_index.py +100 -118
- pixeltable/io/__init__.py +4 -2
- pixeltable/io/datarows.py +8 -7
- pixeltable/io/external_store.py +56 -105
- pixeltable/io/fiftyone.py +13 -13
- pixeltable/io/globals.py +31 -30
- pixeltable/io/hf_datasets.py +61 -16
- pixeltable/io/label_studio.py +74 -70
- pixeltable/io/lancedb.py +3 -0
- pixeltable/io/pandas.py +21 -12
- pixeltable/io/parquet.py +25 -105
- pixeltable/io/table_data_conduit.py +250 -123
- pixeltable/io/utils.py +4 -4
- pixeltable/iterators/__init__.py +2 -1
- pixeltable/iterators/audio.py +26 -25
- pixeltable/iterators/base.py +9 -3
- pixeltable/iterators/document.py +112 -78
- pixeltable/iterators/image.py +12 -15
- pixeltable/iterators/string.py +11 -4
- pixeltable/iterators/video.py +523 -120
- pixeltable/metadata/__init__.py +14 -3
- pixeltable/metadata/converters/convert_13.py +2 -2
- 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_30.py +34 -21
- pixeltable/metadata/converters/convert_34.py +2 -2
- pixeltable/metadata/converters/convert_35.py +9 -0
- pixeltable/metadata/converters/convert_36.py +38 -0
- pixeltable/metadata/converters/convert_37.py +15 -0
- pixeltable/metadata/converters/convert_38.py +39 -0
- pixeltable/metadata/converters/convert_39.py +124 -0
- pixeltable/metadata/converters/convert_40.py +73 -0
- pixeltable/metadata/converters/convert_41.py +12 -0
- pixeltable/metadata/converters/convert_42.py +9 -0
- pixeltable/metadata/converters/convert_43.py +44 -0
- pixeltable/metadata/converters/util.py +20 -31
- pixeltable/metadata/notes.py +9 -0
- pixeltable/metadata/schema.py +140 -53
- pixeltable/metadata/utils.py +74 -0
- pixeltable/mypy/__init__.py +3 -0
- pixeltable/mypy/mypy_plugin.py +123 -0
- pixeltable/plan.py +382 -115
- pixeltable/share/__init__.py +1 -1
- pixeltable/share/packager.py +547 -83
- pixeltable/share/protocol/__init__.py +33 -0
- pixeltable/share/protocol/common.py +165 -0
- pixeltable/share/protocol/operation_types.py +33 -0
- pixeltable/share/protocol/replica.py +119 -0
- pixeltable/share/publish.py +257 -59
- pixeltable/store.py +311 -194
- pixeltable/type_system.py +373 -211
- pixeltable/utils/__init__.py +2 -3
- pixeltable/utils/arrow.py +131 -17
- pixeltable/utils/av.py +298 -0
- pixeltable/utils/azure_store.py +346 -0
- pixeltable/utils/coco.py +6 -6
- pixeltable/utils/code.py +3 -3
- pixeltable/utils/console_output.py +4 -1
- pixeltable/utils/coroutine.py +6 -23
- pixeltable/utils/dbms.py +32 -6
- pixeltable/utils/description_helper.py +4 -5
- pixeltable/utils/documents.py +7 -18
- pixeltable/utils/exception_handler.py +7 -30
- pixeltable/utils/filecache.py +6 -6
- pixeltable/utils/formatter.py +86 -48
- pixeltable/utils/gcs_store.py +295 -0
- pixeltable/utils/http.py +133 -0
- pixeltable/utils/http_server.py +2 -3
- pixeltable/utils/iceberg.py +1 -2
- pixeltable/utils/image.py +17 -0
- pixeltable/utils/lancedb.py +90 -0
- pixeltable/utils/local_store.py +322 -0
- pixeltable/utils/misc.py +5 -0
- pixeltable/utils/object_stores.py +573 -0
- pixeltable/utils/pydantic.py +60 -0
- pixeltable/utils/pytorch.py +5 -6
- pixeltable/utils/s3_store.py +527 -0
- pixeltable/utils/sql.py +26 -0
- pixeltable/utils/system.py +30 -0
- pixeltable-0.5.7.dist-info/METADATA +579 -0
- pixeltable-0.5.7.dist-info/RECORD +227 -0
- {pixeltable-0.3.14.dist-info → pixeltable-0.5.7.dist-info}/WHEEL +1 -1
- pixeltable-0.5.7.dist-info/entry_points.txt +2 -0
- pixeltable/__version__.py +0 -3
- pixeltable/catalog/named_function.py +0 -40
- pixeltable/ext/__init__.py +0 -17
- pixeltable/ext/functions/__init__.py +0 -11
- pixeltable/ext/functions/whisperx.py +0 -77
- pixeltable/utils/media_store.py +0 -77
- pixeltable/utils/s3.py +0 -17
- pixeltable-0.3.14.dist-info/METADATA +0 -434
- pixeltable-0.3.14.dist-info/RECORD +0 -186
- pixeltable-0.3.14.dist-info/entry_points.txt +0 -3
- {pixeltable-0.3.14.dist-info → pixeltable-0.5.7.dist-info/licenses}/LICENSE +0 -0
pixeltable/functions/image.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Pixeltable
|
|
2
|
+
Pixeltable UDFs for `ImageType`.
|
|
3
3
|
|
|
4
4
|
Example:
|
|
5
5
|
```python
|
|
@@ -10,8 +10,7 @@ t.select(t.img_col.convert('L')).collect()
|
|
|
10
10
|
```
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
-
import
|
|
14
|
-
from typing import Optional
|
|
13
|
+
from typing import Any, Literal
|
|
15
14
|
|
|
16
15
|
import PIL.Image
|
|
17
16
|
|
|
@@ -19,6 +18,7 @@ import pixeltable as pxt
|
|
|
19
18
|
import pixeltable.type_system as ts
|
|
20
19
|
from pixeltable.exprs import Expr
|
|
21
20
|
from pixeltable.utils.code import local_public_names
|
|
21
|
+
from pixeltable.utils.image import to_base64
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
@pxt.udf(is_method=True)
|
|
@@ -30,42 +30,37 @@ def b64_encode(img: PIL.Image.Image, image_format: str = 'png') -> str:
|
|
|
30
30
|
img: image
|
|
31
31
|
image_format: image format [supported by PIL](https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#fully-supported-formats)
|
|
32
32
|
"""
|
|
33
|
-
|
|
33
|
+
return to_base64(img, format=image_format)
|
|
34
34
|
|
|
35
|
-
bytes_arr = io.BytesIO()
|
|
36
|
-
img.save(bytes_arr, format=image_format)
|
|
37
|
-
b64_bytes = base64.b64encode(bytes_arr.getvalue())
|
|
38
|
-
return b64_bytes.decode('utf-8')
|
|
39
35
|
|
|
40
|
-
|
|
41
|
-
@pxt.udf(substitute_fn=PIL.Image.alpha_composite, is_method=True)
|
|
36
|
+
@pxt.udf(is_method=True)
|
|
42
37
|
def alpha_composite(im1: PIL.Image.Image, im2: PIL.Image.Image) -> PIL.Image.Image:
|
|
43
38
|
"""
|
|
44
39
|
Alpha composite `im2` over `im1`.
|
|
45
40
|
|
|
46
41
|
Equivalent to [`PIL.Image.alpha_composite()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.alpha_composite)
|
|
47
42
|
"""
|
|
48
|
-
|
|
43
|
+
return PIL.Image.alpha_composite(im1, im2)
|
|
49
44
|
|
|
50
45
|
|
|
51
|
-
@pxt.udf(
|
|
46
|
+
@pxt.udf(is_method=True)
|
|
52
47
|
def blend(im1: PIL.Image.Image, im2: PIL.Image.Image, alpha: float) -> PIL.Image.Image:
|
|
53
48
|
"""
|
|
54
49
|
Return a new image by interpolating between two input images, using a constant alpha.
|
|
55
50
|
|
|
56
51
|
Equivalent to [`PIL.Image.blend()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.blend)
|
|
57
52
|
"""
|
|
58
|
-
|
|
53
|
+
return PIL.Image.blend(im1, im2, alpha)
|
|
59
54
|
|
|
60
55
|
|
|
61
|
-
@pxt.udf(
|
|
56
|
+
@pxt.udf(is_method=True)
|
|
62
57
|
def composite(image1: PIL.Image.Image, image2: PIL.Image.Image, mask: PIL.Image.Image) -> PIL.Image.Image:
|
|
63
58
|
"""
|
|
64
59
|
Return a composite image by blending two images using a mask.
|
|
65
60
|
|
|
66
61
|
Equivalent to [`PIL.Image.composite()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.composite)
|
|
67
62
|
"""
|
|
68
|
-
|
|
63
|
+
return PIL.Image.composite(image1, image2, mask)
|
|
69
64
|
|
|
70
65
|
|
|
71
66
|
# PIL.Image.Image methods
|
|
@@ -96,7 +91,7 @@ def _(self: Expr, mode: str) -> ts.ColumnType:
|
|
|
96
91
|
|
|
97
92
|
|
|
98
93
|
# Image.crop()
|
|
99
|
-
@pxt.udf(
|
|
94
|
+
@pxt.udf(is_method=True)
|
|
100
95
|
def crop(self: PIL.Image.Image, box: tuple[int, int, int, int]) -> PIL.Image.Image:
|
|
101
96
|
"""
|
|
102
97
|
Return a rectangular region from the image. The box is a 4-tuple defining the left, upper, right, and lower pixel
|
|
@@ -105,7 +100,7 @@ def crop(self: PIL.Image.Image, box: tuple[int, int, int, int]) -> PIL.Image.Ima
|
|
|
105
100
|
Equivalent to
|
|
106
101
|
[`PIL.Image.Image.crop()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.crop)
|
|
107
102
|
"""
|
|
108
|
-
|
|
103
|
+
return self.crop(box)
|
|
109
104
|
|
|
110
105
|
|
|
111
106
|
@crop.conditional_return_type
|
|
@@ -118,7 +113,7 @@ def _(self: Expr, box: tuple[int, int, int, int]) -> ts.ColumnType:
|
|
|
118
113
|
|
|
119
114
|
|
|
120
115
|
# Image.getchannel()
|
|
121
|
-
@pxt.udf(
|
|
116
|
+
@pxt.udf(is_method=True)
|
|
122
117
|
def getchannel(self: PIL.Image.Image, channel: int) -> PIL.Image.Image:
|
|
123
118
|
"""
|
|
124
119
|
Return an L-mode image containing a single channel of the original image.
|
|
@@ -129,7 +124,7 @@ def getchannel(self: PIL.Image.Image, channel: int) -> PIL.Image.Image:
|
|
|
129
124
|
Args:
|
|
130
125
|
channel: The channel to extract. This is a 0-based index.
|
|
131
126
|
"""
|
|
132
|
-
|
|
127
|
+
return self.getchannel(channel)
|
|
133
128
|
|
|
134
129
|
|
|
135
130
|
@getchannel.conditional_return_type
|
|
@@ -156,7 +151,7 @@ def get_metadata(self: PIL.Image.Image) -> dict:
|
|
|
156
151
|
|
|
157
152
|
# Image.point()
|
|
158
153
|
@pxt.udf(is_method=True)
|
|
159
|
-
def point(self: PIL.Image.Image, lut: list[int], mode:
|
|
154
|
+
def point(self: PIL.Image.Image, lut: list[int], mode: str | None = None) -> PIL.Image.Image:
|
|
160
155
|
"""
|
|
161
156
|
Map image pixels through a lookup table.
|
|
162
157
|
|
|
@@ -203,7 +198,7 @@ def rotate(self: PIL.Image.Image, angle: int) -> PIL.Image.Image:
|
|
|
203
198
|
return self.rotate(angle)
|
|
204
199
|
|
|
205
200
|
|
|
206
|
-
@pxt.udf(
|
|
201
|
+
@pxt.udf(is_method=True)
|
|
207
202
|
def effect_spread(self: PIL.Image.Image, distance: int) -> PIL.Image.Image:
|
|
208
203
|
"""
|
|
209
204
|
Randomly spread pixels in an image.
|
|
@@ -214,11 +209,11 @@ def effect_spread(self: PIL.Image.Image, distance: int) -> PIL.Image.Image:
|
|
|
214
209
|
Args:
|
|
215
210
|
distance: The distance to spread pixels.
|
|
216
211
|
"""
|
|
217
|
-
|
|
212
|
+
return self.effect_spread(distance)
|
|
218
213
|
|
|
219
214
|
|
|
220
|
-
@pxt.udf(
|
|
221
|
-
def transpose(self: PIL.Image.Image, method:
|
|
215
|
+
@pxt.udf(is_method=True)
|
|
216
|
+
def transpose(self: PIL.Image.Image, method: Literal[0, 1, 2, 3, 4, 5, 6]) -> PIL.Image.Image:
|
|
222
217
|
"""
|
|
223
218
|
Transpose the image.
|
|
224
219
|
|
|
@@ -230,7 +225,7 @@ def transpose(self: PIL.Image.Image, method: int) -> PIL.Image.Image:
|
|
|
230
225
|
[Pillow documentation](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.transpose)
|
|
231
226
|
for a list of supported methods.
|
|
232
227
|
"""
|
|
233
|
-
|
|
228
|
+
return self.transpose(method)
|
|
234
229
|
|
|
235
230
|
|
|
236
231
|
@rotate.conditional_return_type
|
|
@@ -240,8 +235,8 @@ def _(self: Expr) -> ts.ColumnType:
|
|
|
240
235
|
return self.col_type
|
|
241
236
|
|
|
242
237
|
|
|
243
|
-
@pxt.udf(
|
|
244
|
-
def entropy(self: PIL.Image.Image, mask:
|
|
238
|
+
@pxt.udf(is_method=True)
|
|
239
|
+
def entropy(self: PIL.Image.Image, mask: PIL.Image.Image | None = None, extrema: list | None = None) -> float:
|
|
245
240
|
"""
|
|
246
241
|
Returns the entropy of the image, optionally using a mask and extrema.
|
|
247
242
|
|
|
@@ -252,22 +247,22 @@ def entropy(self: PIL.Image.Image, mask: Optional[PIL.Image.Image] = None, extre
|
|
|
252
247
|
mask: An optional mask image.
|
|
253
248
|
extrema: An optional list of extrema.
|
|
254
249
|
"""
|
|
255
|
-
|
|
250
|
+
return self.entropy(mask, extrema) # type: ignore[arg-type]
|
|
256
251
|
|
|
257
252
|
|
|
258
|
-
@pxt.udf(
|
|
259
|
-
def getbands(self: PIL.Image.Image) -> tuple[str]:
|
|
253
|
+
@pxt.udf(is_method=True)
|
|
254
|
+
def getbands(self: PIL.Image.Image) -> tuple[str, ...]:
|
|
260
255
|
"""
|
|
261
256
|
Return a tuple containing the names of the image bands.
|
|
262
257
|
|
|
263
258
|
Equivalent to
|
|
264
259
|
[`PIL.Image.Image.getbands()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.getbands)
|
|
265
260
|
"""
|
|
266
|
-
|
|
261
|
+
return self.getbands()
|
|
267
262
|
|
|
268
263
|
|
|
269
|
-
@pxt.udf(
|
|
270
|
-
def getbbox(self: PIL.Image.Image, *, alpha_only: bool = True) -> tuple[int, int, int, int]:
|
|
264
|
+
@pxt.udf(is_method=True)
|
|
265
|
+
def getbbox(self: PIL.Image.Image, *, alpha_only: bool = True) -> tuple[int, int, int, int] | None:
|
|
271
266
|
"""
|
|
272
267
|
Return a bounding box for the non-zero regions of the image.
|
|
273
268
|
|
|
@@ -277,11 +272,11 @@ def getbbox(self: PIL.Image.Image, *, alpha_only: bool = True) -> tuple[int, int
|
|
|
277
272
|
alpha_only: If `True`, and the image has an alpha channel, trim transparent pixels. Otherwise,
|
|
278
273
|
trim pixels when all channels are zero.
|
|
279
274
|
"""
|
|
280
|
-
|
|
275
|
+
return self.getbbox(alpha_only=alpha_only)
|
|
281
276
|
|
|
282
277
|
|
|
283
|
-
@pxt.udf(
|
|
284
|
-
def getcolors(self: PIL.Image.Image, maxcolors: int = 256) ->
|
|
278
|
+
@pxt.udf(is_method=True)
|
|
279
|
+
def getcolors(self: PIL.Image.Image, maxcolors: int = 256) -> list[tuple[int, int]]:
|
|
285
280
|
"""
|
|
286
281
|
Return a list of colors used in the image, up to a maximum of `maxcolors`.
|
|
287
282
|
|
|
@@ -291,10 +286,10 @@ def getcolors(self: PIL.Image.Image, maxcolors: int = 256) -> tuple[tuple[int, i
|
|
|
291
286
|
Args:
|
|
292
287
|
maxcolors: The maximum number of colors to return.
|
|
293
288
|
"""
|
|
294
|
-
|
|
289
|
+
return self.getcolors(maxcolors)
|
|
295
290
|
|
|
296
291
|
|
|
297
|
-
@pxt.udf(
|
|
292
|
+
@pxt.udf(is_method=True)
|
|
298
293
|
def getextrema(self: PIL.Image.Image) -> tuple[int, int]:
|
|
299
294
|
"""
|
|
300
295
|
Return a 2-tuple containing the minimum and maximum pixel values of the image.
|
|
@@ -302,11 +297,11 @@ def getextrema(self: PIL.Image.Image) -> tuple[int, int]:
|
|
|
302
297
|
Equivalent to
|
|
303
298
|
[`PIL.Image.Image.getextrema()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.getextrema)
|
|
304
299
|
"""
|
|
305
|
-
|
|
300
|
+
return self.getextrema()
|
|
306
301
|
|
|
307
302
|
|
|
308
|
-
@pxt.udf(
|
|
309
|
-
def getpalette(self: PIL.Image.Image, mode:
|
|
303
|
+
@pxt.udf(is_method=True)
|
|
304
|
+
def getpalette(self: PIL.Image.Image, mode: str | None = None) -> list[int] | None:
|
|
310
305
|
"""
|
|
311
306
|
Return the palette of the image, optionally converting it to a different mode.
|
|
312
307
|
|
|
@@ -316,7 +311,7 @@ def getpalette(self: PIL.Image.Image, mode: Optional[str] = None) -> tuple[int]:
|
|
|
316
311
|
Args:
|
|
317
312
|
mode: The mode to convert the palette to.
|
|
318
313
|
"""
|
|
319
|
-
|
|
314
|
+
return self.getpalette(mode)
|
|
320
315
|
|
|
321
316
|
|
|
322
317
|
@pxt.udf(is_method=True)
|
|
@@ -334,21 +329,19 @@ def getpixel(self: PIL.Image.Image, xy: list) -> tuple[int]:
|
|
|
334
329
|
return self.getpixel(tuple(xy))
|
|
335
330
|
|
|
336
331
|
|
|
337
|
-
@pxt.udf(
|
|
338
|
-
def getprojection(self: PIL.Image.Image) -> tuple[int]:
|
|
332
|
+
@pxt.udf(is_method=True)
|
|
333
|
+
def getprojection(self: PIL.Image.Image) -> tuple[list[int], list[int]]:
|
|
339
334
|
"""
|
|
340
335
|
Return two sequences representing the horizontal and vertical projection of the image.
|
|
341
336
|
|
|
342
337
|
Equivalent to
|
|
343
338
|
[`PIL.Image.Image.getprojection()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.getprojection)
|
|
344
339
|
"""
|
|
345
|
-
|
|
340
|
+
return self.getprojection()
|
|
346
341
|
|
|
347
342
|
|
|
348
|
-
@pxt.udf(
|
|
349
|
-
def histogram(
|
|
350
|
-
self: PIL.Image.Image, mask: Optional[PIL.Image.Image] = None, extrema: Optional[list] = None
|
|
351
|
-
) -> list[int]:
|
|
343
|
+
@pxt.udf(is_method=True)
|
|
344
|
+
def histogram(self: PIL.Image.Image, mask: PIL.Image.Image | None = None, extrema: list | None = None) -> list[int]:
|
|
352
345
|
"""
|
|
353
346
|
Return a histogram for the image.
|
|
354
347
|
|
|
@@ -359,16 +352,16 @@ def histogram(
|
|
|
359
352
|
mask: An optional mask image.
|
|
360
353
|
extrema: An optional list of extrema.
|
|
361
354
|
"""
|
|
362
|
-
|
|
355
|
+
return self.histogram(mask, extrema) # type: ignore[arg-type]
|
|
363
356
|
|
|
364
357
|
|
|
365
|
-
@pxt.udf(
|
|
358
|
+
@pxt.udf(is_method=True)
|
|
366
359
|
def quantize(
|
|
367
360
|
self: PIL.Image.Image,
|
|
368
361
|
colors: int = 256,
|
|
369
|
-
method:
|
|
362
|
+
method: Literal[0, 1, 2, 3] | None = None,
|
|
370
363
|
kmeans: int = 0,
|
|
371
|
-
palette:
|
|
364
|
+
palette: PIL.Image.Image | None = None,
|
|
372
365
|
dither: int = PIL.Image.Dither.FLOYDSTEINBERG,
|
|
373
366
|
) -> PIL.Image.Image:
|
|
374
367
|
"""
|
|
@@ -388,11 +381,11 @@ def quantize(
|
|
|
388
381
|
[Pillow documentation](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.quantize)
|
|
389
382
|
for a list of supported methods.
|
|
390
383
|
"""
|
|
391
|
-
|
|
384
|
+
return self.quantize(colors, method, kmeans, palette, dither)
|
|
392
385
|
|
|
393
386
|
|
|
394
|
-
@pxt.udf(
|
|
395
|
-
def reduce(self: PIL.Image.Image, factor: int, box:
|
|
387
|
+
@pxt.udf(is_method=True)
|
|
388
|
+
def reduce(self: PIL.Image.Image, factor: int, box: tuple[int, int, int, int] | None = None) -> PIL.Image.Image:
|
|
396
389
|
"""
|
|
397
390
|
Reduce the image by the given factor.
|
|
398
391
|
|
|
@@ -404,24 +397,89 @@ def reduce(self: PIL.Image.Image, factor: int, box: Optional[tuple[int, int, int
|
|
|
404
397
|
box: An optional 4-tuple of ints providing the source image region to be reduced. The values must be within
|
|
405
398
|
(0, 0, width, height) rectangle. If omitted or None, the entire source is used.
|
|
406
399
|
"""
|
|
407
|
-
|
|
400
|
+
return self.reduce(factor, box)
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
@pxt.udf(is_method=True)
|
|
404
|
+
def thumbnail(
|
|
405
|
+
self: PIL.Image.Image,
|
|
406
|
+
size: tuple[int, int],
|
|
407
|
+
resample: int = PIL.Image.Resampling.LANCZOS,
|
|
408
|
+
reducing_gap: float | None = 2.0,
|
|
409
|
+
) -> PIL.Image.Image:
|
|
410
|
+
"""
|
|
411
|
+
Create a thumbnail of the image.
|
|
412
|
+
|
|
413
|
+
Equivalent to
|
|
414
|
+
[`PIL.Image.Image.thumbnail()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.thumbnail)
|
|
415
|
+
|
|
416
|
+
Args:
|
|
417
|
+
size: The size of the thumbnail, as a tuple of (width, height).
|
|
418
|
+
resample: The resampling filter to use. See the
|
|
419
|
+
[Pillow documentation](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.thumbnail)
|
|
420
|
+
for a list of supported filters.
|
|
421
|
+
reducing_gap: The reducing gap to use.
|
|
422
|
+
"""
|
|
423
|
+
result = self.copy()
|
|
424
|
+
result.thumbnail(size, PIL.Image.Resampling(resample), reducing_gap)
|
|
425
|
+
return result
|
|
408
426
|
|
|
409
427
|
|
|
410
428
|
@pxt.udf(is_property=True)
|
|
411
429
|
def width(self: PIL.Image.Image) -> int:
|
|
430
|
+
"""
|
|
431
|
+
Return the width of the image.
|
|
432
|
+
"""
|
|
412
433
|
return self.width
|
|
413
434
|
|
|
414
435
|
|
|
415
436
|
@pxt.udf(is_property=True)
|
|
416
437
|
def height(self: PIL.Image.Image) -> int:
|
|
438
|
+
"""
|
|
439
|
+
Return the height of the image.
|
|
440
|
+
"""
|
|
417
441
|
return self.height
|
|
418
442
|
|
|
419
443
|
|
|
420
444
|
@pxt.udf(is_property=True)
|
|
421
445
|
def mode(self: PIL.Image.Image) -> str:
|
|
446
|
+
"""
|
|
447
|
+
Return the image mode.
|
|
448
|
+
"""
|
|
422
449
|
return self.mode
|
|
423
450
|
|
|
424
451
|
|
|
452
|
+
def tile_iterator(
|
|
453
|
+
image: Any, tile_size: tuple[int, int], *, overlap: tuple[int, int] = (0, 0)
|
|
454
|
+
) -> tuple[type[pxt.iterators.ComponentIterator], dict[str, Any]]:
|
|
455
|
+
"""
|
|
456
|
+
Iterator over tiles of an image. Each image will be divided into tiles of size `tile_size`, and the tiles will be
|
|
457
|
+
iterated over in row-major order (left-to-right, then top-to-bottom). An optional `overlap` parameter may be
|
|
458
|
+
specified. If the tiles do not exactly cover the image, then the rightmost and bottommost tiles will be padded with
|
|
459
|
+
blackspace, so that the output images all have the exact size `tile_size`.
|
|
460
|
+
|
|
461
|
+
Args:
|
|
462
|
+
image: Image to split into tiles.
|
|
463
|
+
tile_size: Size of each tile, as a pair of integers `[width, height]`.
|
|
464
|
+
overlap: Amount of overlap between adjacent tiles, as a pair of integers `[width, height]`.
|
|
465
|
+
|
|
466
|
+
Examples:
|
|
467
|
+
This example assumes an existing table `tbl` with a column `img` of type `pxt.Image`.
|
|
468
|
+
|
|
469
|
+
Create a view that splits all images into 256x256 tiles with 32 pixels of overlap:
|
|
470
|
+
|
|
471
|
+
>>> pxt.create_view(
|
|
472
|
+
... 'image_tiles',
|
|
473
|
+
... tbl,
|
|
474
|
+
... iterator=image_tile_iterator(tbl.img, tile_size=(256, 256), overlap=(32, 32))
|
|
475
|
+
... )
|
|
476
|
+
"""
|
|
477
|
+
kwargs: dict[str, Any] = {}
|
|
478
|
+
if overlap != (0, 0):
|
|
479
|
+
kwargs['overlap'] = overlap
|
|
480
|
+
return pxt.iterators.image.TileIterator._create(image=image, tile_size=tile_size, **kwargs)
|
|
481
|
+
|
|
482
|
+
|
|
425
483
|
__all__ = local_public_names(__name__)
|
|
426
484
|
|
|
427
485
|
|
pixeltable/functions/json.py
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Pixeltable UDFs for llama.cpp models.
|
|
3
|
+
|
|
4
|
+
Provides integration with llama.cpp for running quantized language models locally,
|
|
5
|
+
supporting chat completions and embeddings with GGUF format models.
|
|
6
|
+
"""
|
|
7
|
+
|
|
1
8
|
from pathlib import Path
|
|
2
|
-
from typing import TYPE_CHECKING, Any
|
|
9
|
+
from typing import TYPE_CHECKING, Any
|
|
3
10
|
|
|
4
11
|
import pixeltable as pxt
|
|
5
12
|
import pixeltable.exceptions as excs
|
|
@@ -14,10 +21,10 @@ if TYPE_CHECKING:
|
|
|
14
21
|
def create_chat_completion(
|
|
15
22
|
messages: list[dict],
|
|
16
23
|
*,
|
|
17
|
-
model_path:
|
|
18
|
-
repo_id:
|
|
19
|
-
repo_filename:
|
|
20
|
-
|
|
24
|
+
model_path: str | None = None,
|
|
25
|
+
repo_id: str | None = None,
|
|
26
|
+
repo_filename: str | None = None,
|
|
27
|
+
model_kwargs: dict[str, Any] | None = None,
|
|
21
28
|
) -> dict:
|
|
22
29
|
"""
|
|
23
30
|
Generate a chat completion from a list of messages.
|
|
@@ -35,14 +42,14 @@ def create_chat_completion(
|
|
|
35
42
|
repo_id: The Hugging Face model repo id (if using a pretrained model).
|
|
36
43
|
repo_filename: A filename or glob pattern to match the model file in the repo (optional, if using a
|
|
37
44
|
pretrained model).
|
|
38
|
-
|
|
39
|
-
`top_p`, and `top_k`. For details, see the
|
|
45
|
+
model_kwargs: Additional keyword args for the llama_cpp `create_chat_completions` API, such as `max_tokens`,
|
|
46
|
+
`temperature`, `top_p`, and `top_k`. For details, see the
|
|
40
47
|
[llama_cpp create_chat_completions documentation](https://llama-cpp-python.readthedocs.io/en/latest/api-reference/#llama_cpp.Llama.create_chat_completion).
|
|
41
48
|
"""
|
|
42
49
|
Env.get().require_package('llama_cpp', min_version=[0, 3, 1])
|
|
43
50
|
|
|
44
|
-
if
|
|
45
|
-
|
|
51
|
+
if model_kwargs is None:
|
|
52
|
+
model_kwargs = {}
|
|
46
53
|
|
|
47
54
|
if (model_path is None) == (repo_id is None):
|
|
48
55
|
raise excs.Error('Exactly one of `model_path` or `repo_id` must be provided.')
|
|
@@ -56,7 +63,7 @@ def create_chat_completion(
|
|
|
56
63
|
else:
|
|
57
64
|
Env.get().require_package('huggingface_hub')
|
|
58
65
|
llm = _lookup_pretrained_model(repo_id, repo_filename, n_gpu_layers)
|
|
59
|
-
return llm.create_chat_completion(messages, **
|
|
66
|
+
return llm.create_chat_completion(messages, **model_kwargs) # type: ignore
|
|
60
67
|
|
|
61
68
|
|
|
62
69
|
def _is_gpu_available() -> bool:
|
|
@@ -81,7 +88,7 @@ def _lookup_local_model(model_path: str, n_gpu_layers: int) -> 'llama_cpp.Llama'
|
|
|
81
88
|
return _model_cache[key]
|
|
82
89
|
|
|
83
90
|
|
|
84
|
-
def _lookup_pretrained_model(repo_id: str, filename:
|
|
91
|
+
def _lookup_pretrained_model(repo_id: str, filename: str | None, n_gpu_layers: int) -> 'llama_cpp.Llama':
|
|
85
92
|
import llama_cpp
|
|
86
93
|
|
|
87
94
|
key = (repo_id, filename, n_gpu_layers)
|
|
@@ -93,8 +100,16 @@ def _lookup_pretrained_model(repo_id: str, filename: Optional[str], n_gpu_layers
|
|
|
93
100
|
return _model_cache[key]
|
|
94
101
|
|
|
95
102
|
|
|
96
|
-
_model_cache: dict[tuple[str, str, int],
|
|
97
|
-
_IS_GPU_AVAILABLE:
|
|
103
|
+
_model_cache: dict[tuple[str, str, int], 'llama_cpp.Llama'] = {}
|
|
104
|
+
_IS_GPU_AVAILABLE: bool | None = None
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def cleanup() -> None:
|
|
108
|
+
for model in _model_cache.values():
|
|
109
|
+
if model._sampler is not None:
|
|
110
|
+
model._sampler.close()
|
|
111
|
+
model.close()
|
|
112
|
+
_model_cache.clear()
|
|
98
113
|
|
|
99
114
|
|
|
100
115
|
__all__ = local_public_names(__name__)
|
pixeltable/functions/math.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Pixeltable
|
|
2
|
+
Pixeltable UDFs for mathematical operations.
|
|
3
3
|
|
|
4
4
|
Example:
|
|
5
5
|
```python
|
|
@@ -12,7 +12,6 @@ t.select(t.float_col.floor()).collect()
|
|
|
12
12
|
|
|
13
13
|
import builtins
|
|
14
14
|
import math
|
|
15
|
-
from typing import Optional
|
|
16
15
|
|
|
17
16
|
import sqlalchemy as sql
|
|
18
17
|
|
|
@@ -80,7 +79,7 @@ def _(self: sql.ColumnElement) -> sql.ColumnElement:
|
|
|
80
79
|
|
|
81
80
|
|
|
82
81
|
@pxt.udf(is_method=True)
|
|
83
|
-
def round(self: float, digits:
|
|
82
|
+
def round(self: float, digits: int | None = None) -> float:
|
|
84
83
|
"""
|
|
85
84
|
Round a number to a given precision in decimal digits.
|
|
86
85
|
|
|
@@ -93,11 +92,74 @@ def round(self: float, digits: Optional[int] = None) -> float:
|
|
|
93
92
|
|
|
94
93
|
|
|
95
94
|
@round.to_sql
|
|
96
|
-
def _(self: sql.ColumnElement, digits:
|
|
95
|
+
def _(self: sql.ColumnElement, digits: sql.ColumnElement | None = None) -> sql.ColumnElement:
|
|
97
96
|
if digits is None:
|
|
98
97
|
return sql.func.round(self)
|
|
99
98
|
else:
|
|
100
|
-
return sql.func.round(sql.cast(self, sql.Numeric), sql.cast(digits, sql.Integer))
|
|
99
|
+
return sql.cast(sql.func.round(sql.cast(self, sql.Numeric), sql.cast(digits, sql.Integer)), sql.Float)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@pxt.udf(is_method=True)
|
|
103
|
+
def pow(self: int, other: int) -> float:
|
|
104
|
+
"""
|
|
105
|
+
Raise `self` to the power of `other`.
|
|
106
|
+
|
|
107
|
+
Equivalent to Python [`self ** other`](https://docs.python.org/3/library/functions.html#pow).
|
|
108
|
+
"""
|
|
109
|
+
return self**other
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
@pow.to_sql
|
|
113
|
+
def _(self: sql.ColumnElement, other: sql.ColumnElement) -> sql.ColumnElement:
|
|
114
|
+
return sql.func.pow(self, other)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@pxt.udf(is_method=True)
|
|
118
|
+
def bitwise_and(self: int, other: int) -> int:
|
|
119
|
+
"""
|
|
120
|
+
Bitwise AND of two integers.
|
|
121
|
+
|
|
122
|
+
Equivalent to Python
|
|
123
|
+
[`self & other`](https://docs.python.org/3/library/stdtypes.html#bitwise-operations-on-integer-types).
|
|
124
|
+
"""
|
|
125
|
+
return self & other
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
@bitwise_and.to_sql
|
|
129
|
+
def _(self: sql.ColumnElement, other: sql.ColumnElement) -> sql.ColumnElement:
|
|
130
|
+
return self.bitwise_and(other)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
@pxt.udf(is_method=True)
|
|
134
|
+
def bitwise_or(self: int, other: int) -> int:
|
|
135
|
+
"""
|
|
136
|
+
Bitwise OR of two integers.
|
|
137
|
+
|
|
138
|
+
Equivalent to Python
|
|
139
|
+
[`self | other`](https://docs.python.org/3/library/stdtypes.html#bitwise-operations-on-integer-types).
|
|
140
|
+
"""
|
|
141
|
+
return self | other
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@bitwise_or.to_sql
|
|
145
|
+
def _(self: sql.ColumnElement, other: sql.ColumnElement) -> sql.ColumnElement:
|
|
146
|
+
return self.bitwise_or(other)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
@pxt.udf(is_method=True)
|
|
150
|
+
def bitwise_xor(self: int, other: int) -> int:
|
|
151
|
+
"""
|
|
152
|
+
Bitwise XOR of two integers.
|
|
153
|
+
|
|
154
|
+
Equivalent to Python
|
|
155
|
+
[`self ^ other`](https://docs.python.org/3/library/stdtypes.html#bitwise-operations-on-integer-types).
|
|
156
|
+
"""
|
|
157
|
+
return self ^ other
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
@bitwise_xor.to_sql
|
|
161
|
+
def _(self: sql.ColumnElement, other: sql.ColumnElement) -> sql.ColumnElement:
|
|
162
|
+
return self.bitwise_xor(other)
|
|
101
163
|
|
|
102
164
|
|
|
103
165
|
__all__ = local_public_names(__name__)
|