pixeltable 0.2.12__py3-none-any.whl → 0.2.14__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 (67) hide show
  1. pixeltable/__init__.py +1 -1
  2. pixeltable/__version__.py +2 -2
  3. pixeltable/catalog/column.py +5 -0
  4. pixeltable/catalog/globals.py +8 -0
  5. pixeltable/catalog/insertable_table.py +2 -2
  6. pixeltable/catalog/table.py +27 -9
  7. pixeltable/catalog/table_version.py +41 -68
  8. pixeltable/catalog/view.py +3 -3
  9. pixeltable/dataframe.py +7 -6
  10. pixeltable/exec/__init__.py +2 -1
  11. pixeltable/exec/expr_eval_node.py +8 -1
  12. pixeltable/exec/row_update_node.py +61 -0
  13. pixeltable/exec/{sql_scan_node.py → sql_node.py} +120 -56
  14. pixeltable/exprs/__init__.py +1 -2
  15. pixeltable/exprs/comparison.py +5 -5
  16. pixeltable/exprs/compound_predicate.py +12 -12
  17. pixeltable/exprs/expr.py +67 -22
  18. pixeltable/exprs/function_call.py +60 -29
  19. pixeltable/exprs/globals.py +2 -0
  20. pixeltable/exprs/in_predicate.py +3 -3
  21. pixeltable/exprs/inline_array.py +18 -11
  22. pixeltable/exprs/is_null.py +5 -5
  23. pixeltable/exprs/method_ref.py +63 -0
  24. pixeltable/ext/__init__.py +9 -0
  25. pixeltable/ext/functions/__init__.py +8 -0
  26. pixeltable/ext/functions/whisperx.py +45 -5
  27. pixeltable/ext/functions/yolox.py +60 -14
  28. pixeltable/func/aggregate_function.py +10 -4
  29. pixeltable/func/callable_function.py +16 -4
  30. pixeltable/func/expr_template_function.py +1 -1
  31. pixeltable/func/function.py +12 -2
  32. pixeltable/func/function_registry.py +26 -9
  33. pixeltable/func/udf.py +32 -4
  34. pixeltable/functions/__init__.py +1 -1
  35. pixeltable/functions/fireworks.py +33 -0
  36. pixeltable/functions/globals.py +36 -1
  37. pixeltable/functions/huggingface.py +155 -7
  38. pixeltable/functions/image.py +242 -40
  39. pixeltable/functions/openai.py +214 -0
  40. pixeltable/functions/string.py +600 -8
  41. pixeltable/functions/timestamp.py +210 -0
  42. pixeltable/functions/together.py +106 -0
  43. pixeltable/functions/video.py +28 -10
  44. pixeltable/functions/whisper.py +32 -0
  45. pixeltable/globals.py +3 -3
  46. pixeltable/io/__init__.py +1 -1
  47. pixeltable/io/globals.py +186 -5
  48. pixeltable/io/label_studio.py +42 -2
  49. pixeltable/io/pandas.py +70 -34
  50. pixeltable/metadata/__init__.py +1 -1
  51. pixeltable/metadata/converters/convert_18.py +39 -0
  52. pixeltable/metadata/notes.py +10 -0
  53. pixeltable/plan.py +82 -7
  54. pixeltable/tool/create_test_db_dump.py +4 -5
  55. pixeltable/tool/doc_plugins/griffe.py +81 -0
  56. pixeltable/tool/doc_plugins/mkdocstrings.py +6 -0
  57. pixeltable/tool/doc_plugins/templates/material/udf.html.jinja +135 -0
  58. pixeltable/type_system.py +15 -14
  59. pixeltable/utils/s3.py +1 -1
  60. pixeltable-0.2.14.dist-info/METADATA +206 -0
  61. {pixeltable-0.2.12.dist-info → pixeltable-0.2.14.dist-info}/RECORD +64 -56
  62. pixeltable-0.2.14.dist-info/entry_points.txt +3 -0
  63. pixeltable/exprs/image_member_access.py +0 -96
  64. pixeltable/exprs/predicate.py +0 -44
  65. pixeltable-0.2.12.dist-info/METADATA +0 -137
  66. {pixeltable-0.2.12.dist-info → pixeltable-0.2.14.dist-info}/LICENSE +0 -0
  67. {pixeltable-0.2.12.dist-info → pixeltable-0.2.14.dist-info}/WHEEL +0 -0
@@ -1,5 +1,17 @@
1
+ """
2
+ Pixeltable [UDFs](https://pixeltable.readme.io/docs/user-defined-functions-udfs) for `ImageType`.
3
+
4
+ Example:
5
+ ```python
6
+ import pixeltable as pxt
7
+
8
+ t = pxt.get_table(...)
9
+ t.select(t.img_col.convert('L')).collect()
10
+ ```
11
+ """
12
+
1
13
  import base64
2
- from typing import Optional, Tuple
14
+ from typing import Optional
3
15
 
4
16
  import PIL.Image
5
17
 
@@ -9,9 +21,15 @@ from pixeltable.utils.code import local_public_names
9
21
  from pixeltable.exprs import Expr
10
22
 
11
23
 
12
- @func.udf
24
+ @func.udf(is_method=True)
13
25
  def b64_encode(img: PIL.Image.Image, image_format: str = 'png') -> str:
14
- # Encode this image as a b64-encoded png.
26
+ """
27
+ Convert image to a base64-encoded string.
28
+
29
+ Args:
30
+ img: image
31
+ image_format: image format [supported by PIL](https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#fully-supported-formats)
32
+ """
15
33
  import io
16
34
 
17
35
  bytes_arr = io.BytesIO()
@@ -20,27 +38,49 @@ def b64_encode(img: PIL.Image.Image, image_format: str = 'png') -> str:
20
38
  return b64_bytes.decode('utf-8')
21
39
 
22
40
 
23
- @func.udf(substitute_fn=PIL.Image.alpha_composite)
41
+ @func.udf(substitute_fn=PIL.Image.alpha_composite, is_method=True)
24
42
  def alpha_composite(im1: PIL.Image.Image, im2: PIL.Image.Image) -> PIL.Image.Image:
43
+ """
44
+ Alpha composite `im2` over `im1`.
45
+
46
+ Equivalent to [`PIL.Image.alpha_composite()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.alpha_composite)
47
+ """
25
48
  pass
26
49
 
27
50
 
28
- @func.udf(substitute_fn=PIL.Image.blend)
51
+ @func.udf(substitute_fn=PIL.Image.blend, is_method=True)
29
52
  def blend(im1: PIL.Image.Image, im2: PIL.Image.Image, alpha: float) -> PIL.Image.Image:
30
- pass
53
+ """
54
+ Return a new image by interpolating between two input images, using a constant alpha.
31
55
 
56
+ Equivalent to [`PIL.Image.blend()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.blend)
57
+ """
58
+ pass
32
59
 
33
- @func.udf(substitute_fn=PIL.Image.composite)
60
+ @func.udf(substitute_fn=PIL.Image.composite, is_method=True)
34
61
  def composite(image1: PIL.Image.Image, image2: PIL.Image.Image, mask: PIL.Image.Image) -> PIL.Image.Image:
62
+ """
63
+ Return a composite image by blending two images using a mask.
64
+
65
+ Equivalent to [`PIL.Image.composite()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.composite)
66
+ """
35
67
  pass
36
68
 
37
69
 
38
70
  # PIL.Image.Image methods
39
71
 
40
-
41
72
  # Image.convert()
42
- @func.udf
73
+ @func.udf(is_method=True)
43
74
  def convert(self: PIL.Image.Image, mode: str) -> PIL.Image.Image:
75
+ """
76
+ Convert the image to a different mode.
77
+
78
+ Equivalent to
79
+ [`PIL.Image.Image.convert()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.convert).
80
+
81
+ Args:
82
+ mode: The mode to convert to. See the [Pillow documentation](https://pillow.readthedocs.io/en/stable/handbook/concepts.html#concept-modes) for a list of supported modes.
83
+ """
44
84
  return self.convert(mode)
45
85
 
46
86
 
@@ -52,23 +92,39 @@ def _(self: Expr, mode: str) -> ts.ColumnType:
52
92
 
53
93
 
54
94
  # Image.crop()
55
- @func.udf(substitute_fn=PIL.Image.Image.crop, param_types=[ts.ImageType(), ts.ArrayType((4,), dtype=ts.IntType())])
56
- def crop(self: PIL.Image.Image, box: Tuple[int, int, int, int]) -> PIL.Image.Image:
95
+ @func.udf(substitute_fn=PIL.Image.Image.crop, param_types=[ts.ImageType(), ts.ArrayType((4,), dtype=ts.IntType())], is_method=True)
96
+ def crop(self: PIL.Image.Image, box: tuple[int, int, int, int]) -> PIL.Image.Image:
97
+ """
98
+ Return a rectangular region from the image. The box is a 4-tuple defining the left, upper, right, and lower pixel
99
+ coordinates.
100
+
101
+ Equivalent to
102
+ [`PIL.Image.Image.crop()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.crop)
103
+ """
57
104
  pass
58
105
 
59
106
 
60
107
  @crop.conditional_return_type
61
- def _(self: Expr, box: Tuple[int, int, int, int]) -> ts.ColumnType:
108
+ def _(self: Expr, box: tuple[int, int, int, int]) -> ts.ColumnType:
62
109
  input_type = self.col_type
63
110
  assert isinstance(input_type, ts.ImageType)
64
- if isinstance(box, list) and all(isinstance(x, int) for x in box):
111
+ if (isinstance(box, list) or isinstance(box, tuple)) and len(box) == 4 and all(isinstance(x, int) for x in box):
65
112
  return ts.ImageType(size=(box[2] - box[0], box[3] - box[1]), mode=input_type.mode, nullable=input_type.nullable)
66
113
  return ts.ImageType(mode=input_type.mode, nullable=input_type.nullable) # we can't compute the size statically
67
114
 
68
115
 
69
116
  # Image.getchannel()
70
- @func.udf(substitute_fn=PIL.Image.Image.getchannel)
117
+ @func.udf(substitute_fn=PIL.Image.Image.getchannel, is_method=True)
71
118
  def getchannel(self: PIL.Image.Image, channel: int) -> PIL.Image.Image:
119
+ """
120
+ Return an L-mode image containing a single channel of the original image.
121
+
122
+ Equivalent to
123
+ [`PIL.Image.Image.getchannel()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.getchannel)
124
+
125
+ Args:
126
+ channel: The channel to extract. This is a 0-based index.
127
+ """
72
128
  pass
73
129
 
74
130
 
@@ -80,31 +136,64 @@ def _(self: Expr) -> ts.ColumnType:
80
136
 
81
137
 
82
138
  # Image.resize()
83
- @func.udf(param_types=[ts.ImageType(), ts.ArrayType((2,), dtype=ts.IntType())])
84
- def resize(self: PIL.Image.Image, size: Tuple[int, int]) -> PIL.Image.Image:
139
+ @func.udf(param_types=[ts.ImageType(), ts.ArrayType((2,), dtype=ts.IntType())], is_method=True)
140
+ def resize(self: PIL.Image.Image, size: tuple[int, int]) -> PIL.Image.Image:
141
+ """
142
+ Return a resized copy of the image. The size parameter is a tuple containing the width and height of the new image.
143
+
144
+ Equivalent to
145
+ [`PIL.Image.Image.resize()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.resize)
146
+ """
85
147
  return self.resize(size)
86
148
 
87
149
 
88
150
  @resize.conditional_return_type
89
- def _(self: Expr, size: Tuple[int, int]) -> ts.ColumnType:
151
+ def _(self: Expr, size: tuple[int, int]) -> ts.ColumnType:
90
152
  input_type = self.col_type
91
153
  assert isinstance(input_type, ts.ImageType)
92
154
  return ts.ImageType(size=size, mode=input_type.mode, nullable=input_type.nullable)
93
155
 
94
156
 
95
157
  # Image.rotate()
96
- @func.udf
158
+ @func.udf(is_method=True)
97
159
  def rotate(self: PIL.Image.Image, angle: int) -> PIL.Image.Image:
160
+ """
161
+ Return a copy of the image rotated by the given angle.
162
+
163
+ Equivalent to
164
+ [`PIL.Image.Image.rotate()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.rotate)
165
+
166
+ Args:
167
+ angle: The angle to rotate the image, in degrees. Positive angles are counter-clockwise.
168
+ """
98
169
  return self.rotate(angle)
99
170
 
100
171
 
101
- @func.udf(substitute_fn=PIL.Image.Image.effect_spread)
172
+ @func.udf(substitute_fn=PIL.Image.Image.effect_spread, is_method=True)
102
173
  def effect_spread(self: PIL.Image.Image, distance: int) -> PIL.Image.Image:
174
+ """
175
+ Randomly spread pixels in an image.
176
+
177
+ Equivalent to
178
+ [`PIL.Image.Image.effect_spread()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.effect_spread)
179
+
180
+ Args:
181
+ distance: The distance to spread pixels.
182
+ """
103
183
  pass
104
184
 
105
185
 
106
- @func.udf(substitute_fn=PIL.Image.Image.transpose)
186
+ @func.udf(substitute_fn=PIL.Image.Image.transpose, is_method=True)
107
187
  def transpose(self: PIL.Image.Image, method: int) -> PIL.Image.Image:
188
+ """
189
+ Transpose the image.
190
+
191
+ Equivalent to
192
+ [`PIL.Image.Image.transpose()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.transpose)
193
+
194
+ Args:
195
+ method: The transpose method. See the [Pillow documentation](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.transpose) for a list of supported methods.
196
+ """
108
197
  pass
109
198
 
110
199
 
@@ -115,53 +204,128 @@ def _(self: Expr) -> ts.ColumnType:
115
204
  return self.col_type
116
205
 
117
206
 
118
- @func.udf(substitute_fn=PIL.Image.Image.entropy)
207
+ @func.udf(substitute_fn=PIL.Image.Image.entropy, is_method=True)
119
208
  def entropy(self: PIL.Image.Image, mask: Optional[PIL.Image.Image] = None, extrema: Optional[list] = None) -> float:
209
+ """
210
+ Returns the entropy of the image, optionally using a mask and extrema.
211
+
212
+ Equivalent to
213
+ [`PIL.Image.Image.entropy()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.entropy)
214
+
215
+ Args:
216
+ mask: An optional mask image.
217
+ extrema: An optional list of extrema.
218
+ """
120
219
  pass
121
220
 
122
221
 
123
- @func.udf(substitute_fn=PIL.Image.Image.getbands)
124
- def getbands(self: PIL.Image.Image) -> Tuple[str]:
222
+ @func.udf(substitute_fn=PIL.Image.Image.getbands, is_method=True)
223
+ def getbands(self: PIL.Image.Image) -> tuple[str]:
224
+ """
225
+ Return a tuple containing the names of the image bands.
226
+
227
+ Equivalent to
228
+ [`PIL.Image.Image.getbands()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.getbands)
229
+ """
125
230
  pass
126
231
 
127
232
 
128
- @func.udf(substitute_fn=PIL.Image.Image.getbbox)
129
- def getbbox(self: PIL.Image.Image) -> Tuple[int, int, int, int]:
233
+ @func.udf(substitute_fn=PIL.Image.Image.getbbox, is_method=True)
234
+ def getbbox(self: PIL.Image.Image, *, alpha_only: bool = True) -> tuple[int, int, int, int]:
235
+ """
236
+ Return a bounding box for the non-zero regions of the image.
237
+
238
+ Equivalent to [`PIL.Image.Image.getbbox()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.getbbox)
239
+
240
+ Args:
241
+ alpha_only: If `True`, and the image has an alpha channel, trim transparent pixels. Otherwise, trim pixels when all channels are zero.
242
+ """
130
243
  pass
131
244
 
132
245
 
133
- @func.udf(substitute_fn=PIL.Image.Image.getcolors)
134
- def getcolors(self: PIL.Image.Image, maxcolors: int) -> Tuple[Tuple[int, int, int], int]:
246
+ @func.udf(substitute_fn=PIL.Image.Image.getcolors, is_method=True)
247
+ def getcolors(self: PIL.Image.Image, maxcolors: int = 256) -> tuple[tuple[int, int, int], int]:
248
+ """
249
+ Return a list of colors used in the image, up to a maximum of `maxcolors`.
250
+
251
+ Equivalent to
252
+ [`PIL.Image.Image.getcolors()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.getcolors)
253
+
254
+ Args:
255
+ maxcolors: The maximum number of colors to return.
256
+ """
135
257
  pass
136
258
 
137
259
 
138
- @func.udf(substitute_fn=PIL.Image.Image.getextrema)
139
- def getextrema(self: PIL.Image.Image) -> Tuple[int, int]:
260
+ @func.udf(substitute_fn=PIL.Image.Image.getextrema, is_method=True)
261
+ def getextrema(self: PIL.Image.Image) -> tuple[int, int]:
262
+ """
263
+ Return a 2-tuple containing the minimum and maximum pixel values of the image.
264
+
265
+ Equivalent to
266
+ [`PIL.Image.Image.getextrema()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.getextrema)
267
+ """
140
268
  pass
141
269
 
142
270
 
143
- @func.udf(substitute_fn=PIL.Image.Image.getpalette)
144
- def getpalette(self: PIL.Image.Image, mode: Optional[str] = None) -> Tuple[int]:
271
+ @func.udf(substitute_fn=PIL.Image.Image.getpalette, is_method=True)
272
+ def getpalette(self: PIL.Image.Image, mode: Optional[str] = None) -> tuple[int]:
273
+ """
274
+ Return the palette of the image, optionally converting it to a different mode.
275
+
276
+ Equivalent to
277
+ [`PIL.Image.Image.getpalette()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.getpalette)
278
+
279
+ Args:
280
+ mode: The mode to convert the palette to.
281
+ """
145
282
  pass
146
283
 
147
284
 
148
- @func.udf(param_types=[ts.ImageType(), ts.ArrayType((2,), dtype=ts.IntType())])
149
- def getpixel(self: PIL.Image.Image, xy: tuple[int, int]) -> Tuple[int]:
285
+ @func.udf(param_types=[ts.ImageType(), ts.ArrayType((2,), dtype=ts.IntType())], is_method=True)
286
+ def getpixel(self: PIL.Image.Image, xy: tuple[int, int]) -> tuple[int]:
287
+ """
288
+ Return the pixel value at the given position. The position `xy` is a tuple containing the x and y coordinates.
289
+
290
+ Equivalent to
291
+ [`PIL.Image.Image.getpixel()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.getpixel)
292
+
293
+ Args:
294
+ xy: The coordinates, given as (x, y).
295
+ """
150
296
  # `xy` will be a list; `tuple(xy)` is necessary for pillow 9 compatibility
151
297
  return self.getpixel(tuple(xy))
152
298
 
153
299
 
154
- @func.udf(substitute_fn=PIL.Image.Image.getprojection)
155
- def getprojection(self: PIL.Image.Image) -> Tuple[int]:
300
+ @func.udf(substitute_fn=PIL.Image.Image.getprojection, is_method=True)
301
+ def getprojection(self: PIL.Image.Image) -> tuple[int]:
302
+ """
303
+ Return two sequences representing the horizontal and vertical projection of the image.
304
+
305
+ Equivalent to
306
+ [`PIL.Image.Image.getprojection()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.getprojection)
307
+ """
156
308
  pass
157
309
 
158
310
 
159
- @func.udf(substitute_fn=PIL.Image.Image.histogram)
160
- def histogram(self: PIL.Image.Image, mask: PIL.Image.Image, extrema: Optional[list] = None) -> Tuple[int]:
311
+ @func.udf(substitute_fn=PIL.Image.Image.histogram, is_method=True)
312
+ def histogram(
313
+ self: PIL.Image.Image, mask: Optional[PIL.Image.Image] = None, extrema: Optional[list] = None
314
+ ) -> list[int]:
315
+ """
316
+ Return a histogram for the image.
317
+
318
+ Equivalent to
319
+ [`PIL.Image.Image.histogram()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.histogram)
320
+
321
+ Args:
322
+ mask: An optional mask image.
323
+ extrema: An optional list of extrema.
324
+ """
161
325
  pass
162
326
 
163
327
 
164
- @func.udf(substitute_fn=PIL.Image.Image.quantize)
328
+ @func.udf(substitute_fn=PIL.Image.Image.quantize, is_method=True)
165
329
  def quantize(
166
330
  self: PIL.Image.Image,
167
331
  colors: int = 256,
@@ -170,14 +334,52 @@ def quantize(
170
334
  palette: Optional[int] = None,
171
335
  dither: int = PIL.Image.Dither.FLOYDSTEINBERG,
172
336
  ) -> PIL.Image.Image:
337
+ """
338
+ Convert the image to 'P' mode with the specified number of colors.
339
+
340
+ Equivalent to
341
+ [`PIL.Image.Image.quantize()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.quantize)
342
+
343
+ Args:
344
+ colors: The number of colors to quantize to.
345
+ method: The quantization method. See the [Pillow documentation](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.quantize) for a list of supported methods.
346
+ kmeans: The number of k-means clusters to use.
347
+ palette: The palette to use.
348
+ dither: The dithering method. See the [Pillow documentation](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.quantize) for a list of supported methods.
349
+ """
173
350
  pass
174
351
 
175
352
 
176
- @func.udf(substitute_fn=PIL.Image.Image.reduce)
177
- def reduce(self: PIL.Image.Image, factor: int, box: Optional[Tuple[int]] = None) -> PIL.Image.Image:
353
+ @func.udf(substitute_fn=PIL.Image.Image.reduce, is_method=True)
354
+ def reduce(self: PIL.Image.Image, factor: int, box: Optional[tuple[int]] = None) -> PIL.Image.Image:
355
+ """
356
+ Reduce the image by the given factor.
357
+
358
+ Equivalent to
359
+ [`PIL.Image.Image.reduce()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.reduce)
360
+
361
+ Args:
362
+ factor: The reduction factor.
363
+ box: An optional 4-tuple of ints providing the source image region to be reduced. The values must be within (0, 0, width, height) rectangle. If omitted or None, the entire source is used.
364
+ """
178
365
  pass
179
366
 
180
367
 
368
+ @func.udf(is_property=True)
369
+ def width(self: PIL.Image.Image) -> int:
370
+ return self.width
371
+
372
+
373
+ @func.udf(is_property=True)
374
+ def height(self: PIL.Image.Image) -> int:
375
+ return self.height
376
+
377
+
378
+ @func.udf(is_property=True)
379
+ def mode(self: PIL.Image.Image) -> str:
380
+ return self.mode
381
+
382
+
181
383
  __all__ = local_public_names(__name__)
182
384
 
183
385
 
@@ -1,3 +1,10 @@
1
+ """
2
+ Pixeltable [UDFs](https://pixeltable.readme.io/docs/user-defined-functions-udfs)
3
+ that wrap various endpoints from the OpenAI API. In order to use them, you must
4
+ first `pip install openai` and configure your OpenAI credentials, as described in
5
+ the [Working with OpenAI](https://pixeltable.readme.io/docs/working-with-openai) tutorial.
6
+ """
7
+
1
8
  import base64
2
9
  import io
3
10
  import pathlib
@@ -51,6 +58,33 @@ def _retry(fn: Callable) -> Callable:
51
58
  def speech(
52
59
  input: str, *, model: str, voice: str, response_format: Optional[str] = None, speed: Optional[float] = None
53
60
  ) -> str:
61
+ """
62
+ Generates audio from the input text.
63
+
64
+ Equivalent to the OpenAI `audio/speech` API endpoint.
65
+ For additional details, see: [https://platform.openai.com/docs/guides/text-to-speech](https://platform.openai.com/docs/guides/text-to-speech)
66
+
67
+ __Requirements:__
68
+
69
+ - `pip install openai`
70
+
71
+ Args:
72
+ input: The text to synthesize into speech.
73
+ model: The model to use for speech synthesis.
74
+ voice: The voice profile to use for speech synthesis. Supported options include:
75
+ `alloy`, `echo`, `fable`, `onyx`, `nova`, and `shimmer`.
76
+
77
+ For details on the other parameters, see: [https://platform.openai.com/docs/api-reference/audio/createSpeech](https://platform.openai.com/docs/api-reference/audio/createSpeech)
78
+
79
+ Returns:
80
+ An audio file containing the synthesized speech.
81
+
82
+ Examples:
83
+ Add a computed column that applies the model `tts-1` to an existing Pixeltable column `tbl.text`
84
+ of the table `tbl`:
85
+
86
+ >>> tbl['audio'] = speech(tbl.text, model='tts-1', voice='nova')
87
+ """
54
88
  content = _retry(_openai_client().audio.speech.create)(
55
89
  input=input, model=model, voice=voice, response_format=_opt(response_format), speed=_opt(speed)
56
90
  )
@@ -77,6 +111,31 @@ def transcriptions(
77
111
  prompt: Optional[str] = None,
78
112
  temperature: Optional[float] = None,
79
113
  ) -> dict:
114
+ """
115
+ Transcribes audio into the input language.
116
+
117
+ Equivalent to the OpenAI `audio/transcriptions` API endpoint.
118
+ For additional details, see: [https://platform.openai.com/docs/guides/speech-to-text](https://platform.openai.com/docs/guides/speech-to-text)
119
+
120
+ __Requirements:__
121
+
122
+ - `pip install openai`
123
+
124
+ Args:
125
+ audio: The audio to transcribe.
126
+ model: The model to use for speech transcription.
127
+
128
+ For details on the other parameters, see: [https://platform.openai.com/docs/api-reference/audio/createTranscription](https://platform.openai.com/docs/api-reference/audio/createTranscription)
129
+
130
+ Returns:
131
+ A dictionary containing the transcription and other metadata.
132
+
133
+ Examples:
134
+ Add a computed column that applies the model `whisper-1` to an existing Pixeltable column `tbl.audio`
135
+ of the table `tbl`:
136
+
137
+ >>> tbl['transcription'] = transcriptions(tbl.audio, model='whisper-1', language='en')
138
+ """
80
139
  file = pathlib.Path(audio)
81
140
  transcription = _retry(_openai_client().audio.transcriptions.create)(
82
141
  file=file, model=model, language=_opt(language), prompt=_opt(prompt), temperature=_opt(temperature)
@@ -86,6 +145,31 @@ def transcriptions(
86
145
 
87
146
  @pxt.udf(param_types=[ts.AudioType(), ts.StringType(), ts.StringType(nullable=True), ts.FloatType(nullable=True)])
88
147
  def translations(audio: str, *, model: str, prompt: Optional[str] = None, temperature: Optional[float] = None) -> dict:
148
+ """
149
+ Translates audio into English.
150
+
151
+ Equivalent to the OpenAI `audio/translations` API endpoint.
152
+ For additional details, see: [https://platform.openai.com/docs/guides/speech-to-text](https://platform.openai.com/docs/guides/speech-to-text)
153
+
154
+ __Requirements:__
155
+
156
+ - `pip install openai`
157
+
158
+ Args:
159
+ audio: The audio to translate.
160
+ model: The model to use for speech transcription and translation.
161
+
162
+ For details on the other parameters, see: [https://platform.openai.com/docs/api-reference/audio/createTranslation](https://platform.openai.com/docs/api-reference/audio/createTranslation)
163
+
164
+ Returns:
165
+ A dictionary containing the translation and other metadata.
166
+
167
+ Examples:
168
+ Add a computed column that applies the model `whisper-1` to an existing Pixeltable column `tbl.audio`
169
+ of the table `tbl`:
170
+
171
+ >>> tbl['translation'] = translations(tbl.audio, model='whisper-1', language='en')
172
+ """
89
173
  file = pathlib.Path(audio)
90
174
  translation = _retry(_openai_client().audio.translations.create)(
91
175
  file=file, model=model, prompt=_opt(prompt), temperature=_opt(temperature)
@@ -118,6 +202,35 @@ def chat_completions(
118
202
  tool_choice: Optional[dict] = None,
119
203
  user: Optional[str] = None,
120
204
  ) -> dict:
205
+ """
206
+ Creates a model response for the given chat conversation.
207
+
208
+ Equivalent to the OpenAI `chat/completions` API endpoint.
209
+ For additional details, see: [https://platform.openai.com/docs/guides/chat-completions](https://platform.openai.com/docs/guides/chat-completions)
210
+
211
+ __Requirements:__
212
+
213
+ - `pip install openai`
214
+
215
+ Args:
216
+ messages: A list of messages to use for chat completion, as described in the OpenAI API documentation.
217
+ model: The model to use for chat completion.
218
+
219
+ For details on the other parameters, see: [https://platform.openai.com/docs/api-reference/chat](https://platform.openai.com/docs/api-reference/chat)
220
+
221
+ Returns:
222
+ A dictionary containing the response and other metadata.
223
+
224
+ Examples:
225
+ Add a computed column that applies the model `gpt-4o-mini` to an existing Pixeltable column `tbl.prompt`
226
+ of the table `tbl`:
227
+
228
+ >>> messages = [
229
+ {'role': 'system', 'content': 'You are a helpful assistant.'},
230
+ {'role': 'user', 'content': tbl.prompt}
231
+ ]
232
+ tbl['response'] = chat_completions(messages, model='gpt-4o-mini')
233
+ """
121
234
  result = _retry(_openai_client().chat.completions.create)(
122
235
  messages=messages,
123
236
  model=model,
@@ -142,6 +255,30 @@ def chat_completions(
142
255
 
143
256
  @pxt.udf
144
257
  def vision(prompt: str, image: PIL.Image.Image, *, model: str) -> str:
258
+ """
259
+ Analyzes an image with the OpenAI vision capability. This is a convenience function that takes an image and
260
+ prompt, and constructs a chat completion request that utilizes OpenAI vision.
261
+
262
+ For additional details, see: [https://platform.openai.com/docs/guides/vision](https://platform.openai.com/docs/guides/vision)
263
+
264
+ __Requirements:__
265
+
266
+ - `pip install openai`
267
+
268
+ Args:
269
+ prompt: A prompt for the OpenAI vision request.
270
+ image: The image to analyze.
271
+ model: The model to use for OpenAI vision.
272
+
273
+ Returns:
274
+ The response from the OpenAI vision API.
275
+
276
+ Examples:
277
+ Add a computed column that applies the model `gpt-4o-mini` to an existing Pixeltable column `tbl.image`
278
+ of the table `tbl`:
279
+
280
+ >>> tbl['response'] = vision("What's in this image?", tbl.image, model='gpt-4o-mini')
281
+ """
145
282
  # TODO(aaron-siegel): Decompose CPU/GPU ops into separate functions
146
283
  bytes_arr = io.BytesIO()
147
284
  image.save(bytes_arr, format='png')
@@ -174,6 +311,33 @@ _embedding_dimensions_cache: dict[str, int] = {
174
311
  def embeddings(
175
312
  input: Batch[str], *, model: str, dimensions: Optional[int] = None, user: Optional[str] = None
176
313
  ) -> Batch[np.ndarray]:
314
+ """
315
+ Creates an embedding vector representing the input text.
316
+
317
+ Equivalent to the OpenAI `embeddings` API endpoint.
318
+ For additional details, see: [https://platform.openai.com/docs/guides/embeddings](https://platform.openai.com/docs/guides/embeddings)
319
+
320
+ __Requirements:__
321
+
322
+ - `pip install openai`
323
+
324
+ Args:
325
+ input: The text to embed.
326
+ model: The model to use for the embedding.
327
+ dimensions: The vector length of the embedding. If not specified, Pixeltable will use
328
+ a default value based on the model.
329
+
330
+ For details on the other parameters, see: [https://platform.openai.com/docs/api-reference/embeddings](https://platform.openai.com/docs/api-reference/embeddings)
331
+
332
+ Returns:
333
+ An array representing the application of the given embedding to `input`.
334
+
335
+ Examples:
336
+ Add a computed column that applies the model `text-embedding-3-small` to an existing
337
+ Pixeltable column `tbl.text` of the table `tbl`:
338
+
339
+ >>> tbl['embed'] = embeddings(tbl.text, model='text-embedding-3-small')
340
+ """
177
341
  result = _retry(_openai_client().embeddings.create)(
178
342
  input=input, model=model, dimensions=_opt(dimensions), user=_opt(user), encoding_format='float'
179
343
  )
@@ -204,6 +368,31 @@ def image_generations(
204
368
  style: Optional[str] = None,
205
369
  user: Optional[str] = None,
206
370
  ) -> PIL.Image.Image:
371
+ """
372
+ Creates an image given a prompt.
373
+
374
+ Equivalent to the OpenAI `images/generations` API endpoint.
375
+ For additional details, see: [https://platform.openai.com/docs/guides/images](https://platform.openai.com/docs/guides/images)
376
+
377
+ __Requirements:__
378
+
379
+ - `pip install openai`
380
+
381
+ Args:
382
+ prompt: Prompt for the image.
383
+ model: The model to use for the generations.
384
+
385
+ For details on the other parameters, see: [https://platform.openai.com/docs/api-reference/images/create](https://platform.openai.com/docs/api-reference/images/create)
386
+
387
+ Returns:
388
+ The generated image.
389
+
390
+ Examples:
391
+ Add a computed column that applies the model `dall-e-2` to an existing
392
+ Pixeltable column `tbl.text` of the table `tbl`:
393
+
394
+ >>> tbl['gen_image'] = image_generations(tbl.text, model='dall-e-2')
395
+ """
207
396
  # TODO(aaron-siegel): Decompose CPU/GPU ops into separate functions
208
397
  result = _retry(_openai_client().images.generate)(
209
398
  prompt=prompt,
@@ -241,6 +430,31 @@ def _(size: Optional[str] = None) -> ts.ImageType:
241
430
 
242
431
  @pxt.udf
243
432
  def moderations(input: str, *, model: Optional[str] = None) -> dict:
433
+ """
434
+ Classifies if text is potentially harmful.
435
+
436
+ Equivalent to the OpenAI `moderations` API endpoint.
437
+ For additional details, see: [https://platform.openai.com/docs/guides/moderation](https://platform.openai.com/docs/guides/moderation)
438
+
439
+ __Requirements:__
440
+
441
+ - `pip install openai`
442
+
443
+ Args:
444
+ input: Text to analyze with the moderations model.
445
+ model: The model to use for moderations.
446
+
447
+ For details on the other parameters, see: [https://platform.openai.com/docs/api-reference/moderations](https://platform.openai.com/docs/api-reference/moderations)
448
+
449
+ Returns:
450
+ Details of the moderations results.
451
+
452
+ Examples:
453
+ Add a computed column that applies the model `text-moderation-stable` to an existing
454
+ Pixeltable column `tbl.input` of the table `tbl`:
455
+
456
+ >>> tbl['moderations'] = moderations(tbl.text, model='text-moderation-stable')
457
+ """
244
458
  result = _retry(_openai_client().moderations.create)(input=input, model=_opt(model))
245
459
  return result.dict()
246
460