pixeltable 0.2.4__py3-none-any.whl → 0.2.6__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 (99) hide show
  1. pixeltable/__init__.py +18 -9
  2. pixeltable/__version__.py +3 -0
  3. pixeltable/catalog/column.py +31 -50
  4. pixeltable/catalog/insertable_table.py +7 -6
  5. pixeltable/catalog/table.py +171 -57
  6. pixeltable/catalog/table_version.py +417 -140
  7. pixeltable/catalog/table_version_path.py +2 -2
  8. pixeltable/dataframe.py +239 -121
  9. pixeltable/env.py +82 -16
  10. pixeltable/exec/__init__.py +2 -1
  11. pixeltable/exec/cache_prefetch_node.py +1 -1
  12. pixeltable/exec/data_row_batch.py +6 -7
  13. pixeltable/exec/expr_eval_node.py +28 -28
  14. pixeltable/exec/in_memory_data_node.py +11 -7
  15. pixeltable/exec/sql_scan_node.py +7 -6
  16. pixeltable/exprs/__init__.py +4 -3
  17. pixeltable/exprs/column_ref.py +9 -0
  18. pixeltable/exprs/comparison.py +3 -3
  19. pixeltable/exprs/data_row.py +5 -1
  20. pixeltable/exprs/expr.py +15 -7
  21. pixeltable/exprs/function_call.py +17 -15
  22. pixeltable/exprs/image_member_access.py +9 -28
  23. pixeltable/exprs/in_predicate.py +96 -0
  24. pixeltable/exprs/inline_array.py +13 -11
  25. pixeltable/exprs/inline_dict.py +15 -13
  26. pixeltable/exprs/literal.py +16 -4
  27. pixeltable/exprs/row_builder.py +15 -41
  28. pixeltable/exprs/similarity_expr.py +65 -0
  29. pixeltable/ext/__init__.py +5 -0
  30. pixeltable/ext/functions/yolox.py +92 -0
  31. pixeltable/func/__init__.py +0 -2
  32. pixeltable/func/aggregate_function.py +18 -15
  33. pixeltable/func/callable_function.py +57 -13
  34. pixeltable/func/expr_template_function.py +20 -3
  35. pixeltable/func/function.py +35 -4
  36. pixeltable/func/globals.py +24 -14
  37. pixeltable/func/signature.py +23 -27
  38. pixeltable/func/udf.py +13 -12
  39. pixeltable/functions/__init__.py +8 -8
  40. pixeltable/functions/eval.py +7 -8
  41. pixeltable/functions/huggingface.py +64 -17
  42. pixeltable/functions/openai.py +36 -3
  43. pixeltable/functions/pil/image.py +61 -64
  44. pixeltable/functions/together.py +21 -0
  45. pixeltable/functions/util.py +11 -0
  46. pixeltable/globals.py +425 -0
  47. pixeltable/index/__init__.py +2 -0
  48. pixeltable/index/base.py +51 -0
  49. pixeltable/index/embedding_index.py +168 -0
  50. pixeltable/io/__init__.py +3 -0
  51. pixeltable/{utils → io}/hf_datasets.py +48 -17
  52. pixeltable/io/pandas.py +148 -0
  53. pixeltable/{utils → io}/parquet.py +58 -33
  54. pixeltable/iterators/__init__.py +1 -1
  55. pixeltable/iterators/base.py +4 -0
  56. pixeltable/iterators/document.py +218 -97
  57. pixeltable/iterators/video.py +8 -9
  58. pixeltable/metadata/__init__.py +7 -3
  59. pixeltable/metadata/converters/convert_12.py +3 -0
  60. pixeltable/metadata/converters/convert_13.py +41 -0
  61. pixeltable/metadata/schema.py +45 -22
  62. pixeltable/plan.py +15 -51
  63. pixeltable/store.py +38 -41
  64. pixeltable/tool/create_test_db_dump.py +39 -4
  65. pixeltable/type_system.py +47 -96
  66. pixeltable/utils/documents.py +42 -12
  67. pixeltable/utils/http_server.py +70 -0
  68. {pixeltable-0.2.4.dist-info → pixeltable-0.2.6.dist-info}/METADATA +14 -10
  69. pixeltable-0.2.6.dist-info/RECORD +119 -0
  70. {pixeltable-0.2.4.dist-info → pixeltable-0.2.6.dist-info}/WHEEL +1 -1
  71. pixeltable/client.py +0 -604
  72. pixeltable/exprs/image_similarity_predicate.py +0 -58
  73. pixeltable/func/batched_function.py +0 -53
  74. pixeltable/tests/conftest.py +0 -177
  75. pixeltable/tests/functions/test_fireworks.py +0 -42
  76. pixeltable/tests/functions/test_functions.py +0 -60
  77. pixeltable/tests/functions/test_huggingface.py +0 -158
  78. pixeltable/tests/functions/test_openai.py +0 -152
  79. pixeltable/tests/functions/test_together.py +0 -111
  80. pixeltable/tests/test_audio.py +0 -65
  81. pixeltable/tests/test_catalog.py +0 -27
  82. pixeltable/tests/test_client.py +0 -21
  83. pixeltable/tests/test_component_view.py +0 -370
  84. pixeltable/tests/test_dataframe.py +0 -439
  85. pixeltable/tests/test_dirs.py +0 -107
  86. pixeltable/tests/test_document.py +0 -120
  87. pixeltable/tests/test_exprs.py +0 -805
  88. pixeltable/tests/test_function.py +0 -324
  89. pixeltable/tests/test_migration.py +0 -43
  90. pixeltable/tests/test_nos.py +0 -54
  91. pixeltable/tests/test_snapshot.py +0 -208
  92. pixeltable/tests/test_table.py +0 -1267
  93. pixeltable/tests/test_transactional_directory.py +0 -42
  94. pixeltable/tests/test_types.py +0 -22
  95. pixeltable/tests/test_video.py +0 -159
  96. pixeltable/tests/test_view.py +0 -530
  97. pixeltable/tests/utils.py +0 -408
  98. pixeltable-0.2.4.dist-info/RECORD +0 -132
  99. {pixeltable-0.2.4.dist-info → pixeltable-0.2.6.dist-info}/LICENSE +0 -0
pixeltable/type_system.py CHANGED
@@ -6,6 +6,8 @@ import enum
6
6
  import json
7
7
  import typing
8
8
  import urllib.parse
9
+ import urllib.request
10
+ from copy import copy
9
11
  from pathlib import Path
10
12
  from typing import Any, Optional, Tuple, Dict, Callable, List, Union, Sequence, Mapping
11
13
 
@@ -223,6 +225,8 @@ class ColumnType:
223
225
  return BoolType()
224
226
  if isinstance(val, datetime.datetime) or isinstance(val, datetime.date):
225
227
  return TimestampType()
228
+ if isinstance(val, PIL.Image.Image):
229
+ return ImageType(width=val.width, height=val.height)
226
230
  if isinstance(val, np.ndarray):
227
231
  col_type = ArrayType.from_literal(val)
228
232
  if col_type is not None:
@@ -293,7 +297,7 @@ class ColumnType:
293
297
  parsed = urllib.parse.urlparse(val)
294
298
  if parsed.scheme != '' and parsed.scheme != 'file':
295
299
  return
296
- path = Path(urllib.parse.unquote(parsed.path))
300
+ path = Path(urllib.parse.unquote(urllib.request.url2pathname(parsed.path)))
297
301
  if not path.is_file():
298
302
  raise TypeError(f'File not found: {str(path)}')
299
303
  else:
@@ -369,37 +373,11 @@ class ColumnType:
369
373
  return self.is_image_type() or self.is_video_type() or self.is_audio_type() or self.is_document_type()
370
374
 
371
375
  @abc.abstractmethod
372
- def to_sql(self) -> str:
373
- """
374
- Return corresponding Postgres type.
375
- """
376
- pass
377
-
378
- @abc.abstractmethod
379
- def to_sa_type(self) -> Any:
376
+ def to_sa_type(self) -> sql.types.TypeEngine:
380
377
  """
381
378
  Return corresponding SQLAlchemy type.
382
- return type Any: there doesn't appear to be a superclass for the sqlalchemy types
383
379
  """
384
- assert self._type != self.Type.INVALID
385
- if self._type == self.Type.STRING:
386
- return sql.String
387
- if self._type == self.Type.INT:
388
- return sql.Integer
389
- if self._type == self.Type.FLOAT:
390
- return sql.Float
391
- if self._type == self.Type.BOOL:
392
- return sql.Boolean
393
- if self._type == self.Type.TIMESTAMP:
394
- return sql.TIMESTAMP
395
- if self._type == self.Type.IMAGE:
396
- # the URL
397
- return sql.String
398
- if self._type == self.Type.JSON:
399
- return sql.dialects.postgresql.JSONB
400
- if self._type == self.Type.ARRAY:
401
- return sql.VARBINARY
402
- assert False
380
+ pass
403
381
 
404
382
  @staticmethod
405
383
  def no_conversion(v: Any) -> Any:
@@ -421,10 +399,7 @@ class InvalidType(ColumnType):
421
399
  def __init__(self, nullable: bool = False):
422
400
  super().__init__(self.Type.INVALID, nullable=nullable)
423
401
 
424
- def to_sql(self) -> str:
425
- assert False
426
-
427
- def to_sa_type(self) -> Any:
402
+ def to_sa_type(self) -> sql.types.TypeEngine:
428
403
  assert False
429
404
 
430
405
  def print_value(self, val: Any) -> str:
@@ -433,6 +408,7 @@ class InvalidType(ColumnType):
433
408
  def _validate_literal(self, val: Any) -> None:
434
409
  assert False
435
410
 
411
+
436
412
  class StringType(ColumnType):
437
413
  def __init__(self, nullable: bool = False):
438
414
  super().__init__(self.Type.STRING, nullable=nullable)
@@ -448,11 +424,8 @@ class StringType(ColumnType):
448
424
  return None
449
425
  return convert
450
426
 
451
- def to_sql(self) -> str:
452
- return 'VARCHAR'
453
-
454
- def to_sa_type(self) -> str:
455
- return sql.String
427
+ def to_sa_type(self) -> sql.types.TypeEngine:
428
+ return sql.String()
456
429
 
457
430
  def print_value(self, val: Any) -> str:
458
431
  return f"'{val}'"
@@ -469,15 +442,13 @@ class StringType(ColumnType):
469
442
  return val.replace('\x00', ' ')
470
443
  return val
471
444
 
445
+
472
446
  class IntType(ColumnType):
473
447
  def __init__(self, nullable: bool = False):
474
448
  super().__init__(self.Type.INT, nullable=nullable)
475
449
 
476
- def to_sql(self) -> str:
477
- return 'BIGINT'
478
-
479
- def to_sa_type(self) -> str:
480
- return sql.BigInteger
450
+ def to_sa_type(self) -> sql.types.TypeEngine:
451
+ return sql.BigInteger()
481
452
 
482
453
  def _validate_literal(self, val: Any) -> None:
483
454
  if not isinstance(val, int):
@@ -488,11 +459,8 @@ class FloatType(ColumnType):
488
459
  def __init__(self, nullable: bool = False):
489
460
  super().__init__(self.Type.FLOAT, nullable=nullable)
490
461
 
491
- def to_sql(self) -> str:
492
- return 'FLOAT'
493
-
494
- def to_sa_type(self) -> str:
495
- return sql.Float
462
+ def to_sa_type(self) -> sql.types.TypeEngine:
463
+ return sql.Float()
496
464
 
497
465
  def _validate_literal(self, val: Any) -> None:
498
466
  if not isinstance(val, float):
@@ -503,15 +471,13 @@ class FloatType(ColumnType):
503
471
  return float(val)
504
472
  return val
505
473
 
474
+
506
475
  class BoolType(ColumnType):
507
476
  def __init__(self, nullable: bool = False):
508
477
  super().__init__(self.Type.BOOL, nullable=nullable)
509
478
 
510
- def to_sql(self) -> str:
511
- return 'BOOLEAN'
512
-
513
- def to_sa_type(self) -> str:
514
- return sql.Boolean
479
+ def to_sa_type(self) -> sql.types.TypeEngine:
480
+ return sql.Boolean()
515
481
 
516
482
  def _validate_literal(self, val: Any) -> None:
517
483
  if not isinstance(val, bool):
@@ -522,15 +488,13 @@ class BoolType(ColumnType):
522
488
  return bool(val)
523
489
  return val
524
490
 
491
+
525
492
  class TimestampType(ColumnType):
526
493
  def __init__(self, nullable: bool = False):
527
494
  super().__init__(self.Type.TIMESTAMP, nullable=nullable)
528
495
 
529
- def to_sql(self) -> str:
530
- return 'INTEGER'
531
-
532
- def to_sa_type(self) -> str:
533
- return sql.TIMESTAMP
496
+ def to_sa_type(self) -> sql.types.TypeEngine:
497
+ return sql.TIMESTAMP()
534
498
 
535
499
  def _validate_literal(self, val: Any) -> None:
536
500
  if not isinstance(val, datetime.datetime) and not isinstance(val, datetime.date):
@@ -541,6 +505,7 @@ class TimestampType(ColumnType):
541
505
  return datetime.datetime.fromisoformat(val)
542
506
  return val
543
507
 
508
+
544
509
  class JsonType(ColumnType):
545
510
  # TODO: type_spec also needs to be able to express lists
546
511
  def __init__(self, type_spec: Optional[Dict[str, ColumnType]] = None, nullable: bool = False):
@@ -563,14 +528,13 @@ class JsonType(ColumnType):
563
528
  }
564
529
  return cls(type_spec, nullable=d['nullable'])
565
530
 
566
- def to_sql(self) -> str:
567
- return 'JSONB'
568
-
569
- def to_sa_type(self) -> str:
570
- return sql.dialects.postgresql.JSONB
531
+ def to_sa_type(self) -> sql.types.TypeEngine:
532
+ return sql.dialects.postgresql.JSONB()
571
533
 
572
534
  def print_value(self, val: Any) -> str:
573
535
  val_type = self.infer_literal_type(val)
536
+ if val_type is None:
537
+ return super().print_value(val)
574
538
  if val_type == self:
575
539
  return str(val)
576
540
  return val_type.print_value(val)
@@ -588,6 +552,7 @@ class JsonType(ColumnType):
588
552
  val = list(val)
589
553
  return val
590
554
 
555
+
591
556
  class ArrayType(ColumnType):
592
557
  def __init__(
593
558
  self, shape: Tuple[Union[int, None], ...], dtype: ColumnType, nullable: bool = False):
@@ -668,11 +633,8 @@ class ArrayType(ColumnType):
668
633
  return np.array(val, dtype=self.numpy_dtype())
669
634
  return val
670
635
 
671
- def to_sql(self) -> str:
672
- return 'BYTEA'
673
-
674
- def to_sa_type(self) -> str:
675
- return sql.LargeBinary
636
+ def to_sa_type(self) -> sql.types.TypeEngine:
637
+ return sql.LargeBinary()
676
638
 
677
639
  def numpy_dtype(self) -> np.dtype:
678
640
  if self.dtype == self.Type.INT:
@@ -773,11 +735,8 @@ class ImageType(ColumnType):
773
735
  return img
774
736
  return convert
775
737
 
776
- def to_sql(self) -> str:
777
- return 'VARCHAR'
778
-
779
- def to_sa_type(self) -> str:
780
- return sql.String
738
+ def to_sa_type(self) -> sql.types.TypeEngine:
739
+ return sql.String()
781
740
 
782
741
  def _validate_literal(self, val: Any) -> None:
783
742
  if isinstance(val, PIL.Image.Image):
@@ -791,16 +750,14 @@ class ImageType(ColumnType):
791
750
  except PIL.UnidentifiedImageError:
792
751
  raise excs.Error(f'Not a valid image: {val}') from None
793
752
 
753
+
794
754
  class VideoType(ColumnType):
795
755
  def __init__(self, nullable: bool = False):
796
756
  super().__init__(self.Type.VIDEO, nullable=nullable)
797
757
 
798
- def to_sql(self) -> str:
758
+ def to_sa_type(self) -> sql.types.TypeEngine:
799
759
  # stored as a file path
800
- return 'VARCHAR'
801
-
802
- def to_sa_type(self) -> str:
803
- return sql.String
760
+ return sql.String()
804
761
 
805
762
  def _validate_literal(self, val: Any) -> None:
806
763
  self._validate_file_path(val)
@@ -825,16 +782,14 @@ class VideoType(ColumnType):
825
782
  except av.AVError:
826
783
  raise excs.Error(f'Not a valid video: {val}') from None
827
784
 
785
+
828
786
  class AudioType(ColumnType):
829
787
  def __init__(self, nullable: bool = False):
830
788
  super().__init__(self.Type.AUDIO, nullable=nullable)
831
789
 
832
- def to_sql(self) -> str:
790
+ def to_sa_type(self) -> sql.types.TypeEngine:
833
791
  # stored as a file path
834
- return 'VARCHAR'
835
-
836
- def to_sa_type(self) -> str:
837
- return sql.String
792
+ return sql.String()
838
793
 
839
794
  def _validate_literal(self, val: Any) -> None:
840
795
  self._validate_file_path(val)
@@ -854,6 +809,7 @@ class AudioType(ColumnType):
854
809
  except av.AVError as e:
855
810
  raise excs.Error(f'Not a valid audio file: {val}\n{e}') from None
856
811
 
812
+
857
813
  class DocumentType(ColumnType):
858
814
  @enum.unique
859
815
  class DocumentFormat(enum.Enum):
@@ -872,12 +828,9 @@ class DocumentType(ColumnType):
872
828
  else:
873
829
  self._doc_formats = [t for t in self.DocumentFormat]
874
830
 
875
- def to_sql(self) -> str:
831
+ def to_sa_type(self) -> sql.types.TypeEngine:
876
832
  # stored as a file path
877
- return 'VARCHAR'
878
-
879
- def to_sa_type(self) -> str:
880
- return sql.String
833
+ return sql.String()
881
834
 
882
835
  def _validate_literal(self, val: Any) -> None:
883
836
  self._validate_file_path(val)
@@ -885,11 +838,9 @@ class DocumentType(ColumnType):
885
838
  def validate_media(self, val: Any) -> None:
886
839
  assert isinstance(val, str)
887
840
  from pixeltable.utils.documents import get_document_handle
888
- with open(val, 'r', encoding='utf8') as fh:
889
- try:
890
- s = fh.read()
891
- dh = get_document_handle(s)
892
- if dh is None:
893
- raise excs.Error(f'Not a recognized document format: {val}')
894
- except Exception as e:
895
- raise excs.Error(f'Not a recognized document format: {val}') from None
841
+ try:
842
+ dh = get_document_handle(val)
843
+ if dh is None:
844
+ raise excs.Error(f'Not a recognized document format: {val}')
845
+ except Exception as e:
846
+ raise excs.Error(f'Not a recognized document format: {val}') from None
@@ -9,31 +9,61 @@ class DocumentHandle:
9
9
  format: ts.DocumentType.DocumentFormat
10
10
  bs_doc: Optional['bs4.BeautifulSoup'] = None
11
11
  md_ast: Optional[Dict] = None
12
+ pdf_doc: Optional['fitz.Document'] = None
12
13
 
14
+ def get_document_handle(path: str) -> Optional[DocumentHandle]:
15
+ # try pdf first, because a correct PDF is a binary format that
16
+ # would trigger encoding exceptions if oppened as utf8.
17
+ pdf_doc = get_pdf_handle(path)
18
+ if pdf_doc is not None:
19
+ return DocumentHandle(format=ts.DocumentType.DocumentFormat.PDF, pdf_doc=pdf_doc)
20
+ # currently the rest of the types are text-based, so we can open them in utf8 mode once
21
+ try:
22
+ with open(path, 'r', encoding='utf8') as file:
23
+ contents = file.read()
24
+ except UnicodeDecodeError:
25
+ # not pdf, and also not valid text file
26
+ return None
13
27
 
14
- def get_document_handle(s: str) -> Optional[DocumentHandle]:
15
- bs_doc = get_html_handle(s)
28
+ # bs4 will appear to succeed for md files as well.
29
+ # this will break most markdown files at the moment.
30
+ bs_doc = get_html_handle(contents)
16
31
  if bs_doc is not None:
17
32
  return DocumentHandle(format=ts.DocumentType.DocumentFormat.HTML, bs_doc=bs_doc)
18
- md_ast = get_markdown_handle(s)
33
+
34
+ md_ast = get_markdown_handle(contents)
19
35
  if md_ast is not None:
20
36
  return DocumentHandle(format=ts.DocumentType.DocumentFormat.MD, md_ast=md_ast)
37
+
21
38
  return None
22
39
 
23
- def get_html_handle(s: str) -> Optional['bs4.BeautifulSoup']:
40
+ def get_html_handle(text: str) -> Optional['bs4.BeautifulSoup']:
24
41
  import bs4
25
42
  try:
26
- doc = bs4.BeautifulSoup(s, 'html.parser')
27
- except Exception as e:
43
+ doc = bs4.BeautifulSoup(text, 'html.parser')
44
+ if doc.find() is None:
45
+ return None
46
+ return doc
47
+ except Exception:
28
48
  return None
29
- if doc.find() is None:
30
- return None
31
- return doc
32
49
 
33
- def get_markdown_handle(s: str) -> Optional[Dict]:
50
+ def get_markdown_handle(text: str) -> Optional[Dict]:
34
51
  import mistune
35
52
  try:
36
53
  md_ast = mistune.create_markdown(renderer=None)
37
- return md_ast(s)
38
- except Exception as e:
54
+ return md_ast(text)
55
+ except Exception:
39
56
  return None
57
+
58
+ def get_pdf_handle(path : str) -> Optional['fitz.Document']:
59
+ import fitz # aka pymupdf
60
+ try:
61
+ doc = fitz.open(path)
62
+ # check pdf (bc it will work for images)
63
+ if not doc.is_pdf:
64
+ return None
65
+ # try to read one page
66
+ next(page for page in doc)
67
+ return doc
68
+ except Exception:
69
+ return None
@@ -0,0 +1,70 @@
1
+ import http
2
+ import http.server
3
+ import logging
4
+ import urllib
5
+ import posixpath
6
+ import pathlib
7
+ import os
8
+ import string
9
+
10
+ _logger = logging.getLogger('pixeltable.http.server')
11
+
12
+
13
+ def get_file_uri(http_address: str, file_path: str) -> str:
14
+ """Get the URI for a file path, with the given prefix.
15
+ Used in the client to generate a URI
16
+ """
17
+ abs_path = pathlib.Path(file_path)
18
+ assert abs_path.is_absolute()
19
+ url = urllib.request.pathname2url(str(abs_path))
20
+ return f'{http_address}{url}'
21
+
22
+
23
+ class AbsolutePathHandler(http.server.SimpleHTTPRequestHandler):
24
+ """Serves all absolute paths, not just the current directory"""
25
+ def translate_path(self, path: str) -> str:
26
+ """
27
+ Translate a /-separated PATH to the local filename syntax.
28
+ overrides http.server.SimpleHTTPRequestHandler.translate_path
29
+
30
+ This is only useful for file serving.
31
+
32
+ Code initially taken from there:
33
+ https://github.com/python/cpython/blob/f5406ef454662b98df107775d18ff71ae6849618/Lib/http/server.py#L834
34
+ """
35
+ _logger.info(f'translate path {path=}')
36
+ # abandon query parameters, taken from http.server.SimpleHTTPRequestHandler
37
+ path = path.split('?', 1)[0]
38
+ path = path.split('#', 1)[0]
39
+
40
+ path = pathlib.Path(urllib.request.url2pathname(path))
41
+ return str(path)
42
+
43
+ def log_message(self, format, *args) -> None:
44
+ """override logging to stderr in http.server.BaseHTTPRequestHandler"""
45
+ message = format % args
46
+ _logger.info(message.translate(self._control_char_table))
47
+
48
+
49
+ class LoggingHTTPServer(http.server.ThreadingHTTPServer):
50
+ """Avoids polluting stdout and stderr"""
51
+
52
+ def handle_error(self, request, client_address) -> None:
53
+ """override socketserver.TCPServer.handle_error which prints directly to sys.stderr"""
54
+ import traceback
55
+
56
+ _logger.error(
57
+ f'Exception occurred during processing of {request=} from {client_address=}\
58
+ \nbacktrace:\n{traceback.format_exc()}\n----\n'
59
+ )
60
+
61
+
62
+ def make_server(address: str, port: int) -> http.server.HTTPServer:
63
+ """Create a file server with pixeltable specific config """
64
+ return LoggingHTTPServer((address, port), AbsolutePathHandler)
65
+
66
+
67
+ if __name__ == '__main__':
68
+ httpd = make_server('127.0.0.1', 8000)
69
+ print(f'about to server HTTP on {httpd.server_address}')
70
+ httpd.serve_forever()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pixeltable
3
- Version: 0.2.4
3
+ Version: 0.2.6
4
4
  Summary: Pixeltable: The Multimodal AI Data Plane
5
5
  Author: Marcel Kornacker
6
6
  Author-email: marcelk@gmail.com
@@ -13,19 +13,22 @@ Classifier: Programming Language :: Python :: 3.12
13
13
  Requires-Dist: av (>=10.0.0)
14
14
  Requires-Dist: beautifulsoup4 (>=4.0.0,<5.0.0)
15
15
  Requires-Dist: cloudpickle (>=2.2.1,<3.0.0)
16
+ Requires-Dist: ftfy (>=6.2.0,<7.0.0)
16
17
  Requires-Dist: jinja2 (>=3.1.3,<4.0.0)
17
18
  Requires-Dist: jmespath (>=1.0.1,<2.0.0)
18
- Requires-Dist: numpy (>=1.26)
19
+ Requires-Dist: mistune (>=3.0.2,<4.0.0)
20
+ Requires-Dist: numpy (>=1.25)
19
21
  Requires-Dist: opencv-python-headless (>=4.7.0.68,<5.0.0.0)
20
22
  Requires-Dist: pandas (>=2.0,<3.0)
21
- Requires-Dist: pgserver (==0.1.0)
23
+ Requires-Dist: pgserver (==0.1.2)
22
24
  Requires-Dist: pgvector (>=0.2.1,<0.3.0)
23
- Requires-Dist: pillow (>=10.0)
25
+ Requires-Dist: pillow (>=9.3.0)
24
26
  Requires-Dist: psutil (>=5.9.5,<6.0.0)
25
27
  Requires-Dist: psycopg2-binary (>=2.9.5,<3.0.0)
28
+ Requires-Dist: pymupdf (>=1.24.1,<2.0.0)
26
29
  Requires-Dist: pyyaml (>=6.0.1,<7.0.0)
27
- Requires-Dist: regex (>=2022.10.31,<2023.0.0)
28
30
  Requires-Dist: requests (>=2.31.0,<3.0.0)
31
+ Requires-Dist: setuptools (==69.1.1)
29
32
  Requires-Dist: sqlalchemy-utils (>=0.41.1,<0.42.0)
30
33
  Requires-Dist: sqlalchemy[mypy] (>=2.0.23,<3.0.0)
31
34
  Requires-Dist: tenacity (>=8.2,<9.0)
@@ -33,13 +36,13 @@ Requires-Dist: tqdm (>=4.64.1,<5.0.0)
33
36
  Description-Content-Type: text/markdown
34
37
 
35
38
  <div align="center">
36
- <img src="docs/pixeltable-banner.png" width="45%"/>
39
+ <img src="https://raw.githubusercontent.com/pixeltable/pixeltable/master/docs/pixeltable-banner.png" alt="Pixeltable" width="45%" />
37
40
 
38
41
  # Unifying Data, Models, and Orchestration for AI Products
39
42
 
40
43
  [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
41
44
  &nbsp;&nbsp;
42
- ![pytest status](https://github.com/pixeltable/pixeltable/actions/workflows/pytest.yml/badge.svg)
45
+ [![pytest status](https://github.com/pixeltable/pixeltable/actions/workflows/pytest.yml/badge.svg)](https://github.com/pixeltable/pixeltable/actions)
43
46
 
44
47
  [Installation](https://pixeltable.github.io/pixeltable/getting-started/) | [Documentation](https://pixeltable.github.io/pixeltable/)
45
48
  </div>
@@ -60,11 +63,12 @@ Learn the basics of Pixeltable through interactive examples. View the notebooks
60
63
  ### Pixeltable Basics
61
64
  In this tutorial, we'll survey how to create tables, populate them with data, and enhance them with built-in and user-defined transformations and AI operations.
62
65
 
63
- [![Open in Kaggle](https://kaggle.com/static/images/open-in-kaggle.svg)](https://www.kaggle.com/code/brunep/pixeltable-basics) <a target="_blank" href="https://colab.research.google.com/github/pixeltable/pixeltable/blob/master/docs/tutorials/pixeltable-basics.ipynb"> <img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/> </a>
66
+ [![Kaggle](https://kaggle.com/static/images/open-in-kaggle.svg)](https://kaggle.com/kernels/welcome?src=https://github.com/pixeltable/pixeltable/blob/master/docs/tutorials/pixeltable-basics.ipynb)&nbsp;&nbsp;
67
+ <a target="_blank" href="https://colab.research.google.com/github/pixeltable/pixeltable/blob/master/docs/tutorials/pixeltable-basics.ipynb"> <img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/> </a>
64
68
 
65
69
 
66
70
  ## 💾 Installation
67
- Pixeltable works with Python 3.9, 3.10, or 3.11 running on Linux or MacOS.
71
+ Pixeltable works with Python 3.9, 3.10, 3.11, or 3.12 running on Linux, MacOS, or Windows.
68
72
 
69
73
  ```
70
74
  pip install pixeltable
@@ -74,7 +78,7 @@ To verify that it's working:
74
78
 
75
79
  ```
76
80
  import pixeltable as pxt
77
- cl = pxt.Client()
81
+ pxt.init()
78
82
  ```
79
83
 
80
84
  For more detailed installation instructions, see the
@@ -0,0 +1,119 @@
1
+ pixeltable/__init__.py,sha256=TGVKvEpabDRHNqsTYxdDgwU9rsDC9qLDL3D_tjyWemw,1040
2
+ pixeltable/__version__.py,sha256=k6bIPFFhfyfrj1i4diDW-baOOlmqe9QpqWcDh7d1ErM,112
3
+ pixeltable/catalog/__init__.py,sha256=E41bxaPeQIcgRYzTWc2vkDOboQhRymrJf4IcHQO7o_8,453
4
+ pixeltable/catalog/catalog.py,sha256=0TYWB1R6YBp9qCkWF7kCcX2Yw70UuburKKIemv5L1Js,7908
5
+ pixeltable/catalog/column.py,sha256=2qZ3Wxvi-kwiLseeZtXFiXWrHHzzktUa_2skPSP1FGs,8088
6
+ pixeltable/catalog/dir.py,sha256=pG1nMpG123POo6WMSHhAmnwXOQ26uUJfUcbzL-Jb4ws,919
7
+ pixeltable/catalog/globals.py,sha256=yLEGNbsSnLzjWNHVJacfjA9hbw13Q6QXLOSCRmdTlq0,943
8
+ pixeltable/catalog/insertable_table.py,sha256=1yGwuoMNbtBJQRDweEoH7hgxAI4uOB1k2VGpBAmsJxQ,8168
9
+ pixeltable/catalog/named_function.py,sha256=a96gnKtx-nz5_MzDIiD4t4Hxqdjkg9ZtijRQxvWA5WQ,1147
10
+ pixeltable/catalog/path.py,sha256=QgccEi_QOfaKt8YsR2zLtd_z7z7QQkU_1kprJFi2SPQ,1677
11
+ pixeltable/catalog/path_dict.py,sha256=xfvxg1Ze5jZCARUGASF2DRbQPh7pRVTYhuJ_u82gYUo,5941
12
+ pixeltable/catalog/schema_object.py,sha256=-UxmPLbuEBqJiJi_GGRbFdr7arAFxTqs4bt6TFmSt3M,1059
13
+ pixeltable/catalog/table.py,sha256=LgTWRrZcqx85bkW1kW9wWyDvFp15m8e5PfBYkY6E8JE,31252
14
+ pixeltable/catalog/table_version.py,sha256=7_sRbeado0Xu6hbsIAwiz3D35s-RdD5KI6csxhg5DMg,48865
15
+ pixeltable/catalog/table_version_path.py,sha256=2Ofzd0n36flcNm86KWwIWDBAfgnV5Z-FxAHdMSPgMLc,5482
16
+ pixeltable/catalog/view.py,sha256=BIL3s4DV3tWbOcqtqnhn46B2UvLaBhppfJUlNEt5nec,9734
17
+ pixeltable/dataframe.py,sha256=lzSzR7mi9C4BO39fNXYo64k3KxILyG_Z7eET6DXTgKY,31922
18
+ pixeltable/env.py,sha256=8OjBv3Jvd-74KepYYyIpLmhl2S85g-S14qDIywcbRpo,17971
19
+ pixeltable/exceptions.py,sha256=MSP9zeL0AmXT93XqjdvgGN4rzno1_KRrGriq6hpemnw,376
20
+ pixeltable/exec/__init__.py,sha256=RK7SKvrQ7Ky3G_LXDP4Bf7lHmMM_uYZl8dJaZYs0FjY,454
21
+ pixeltable/exec/aggregation_node.py,sha256=cf6rVAgrGh_uaMrCIgXJIwQTmbcboJlnrH_MmPIQSd0,3321
22
+ pixeltable/exec/cache_prefetch_node.py,sha256=d5pEuR6AtJQkEVy9X3XeYFI_q0szMtoNAH96vYdtBE0,5241
23
+ pixeltable/exec/component_iteration_node.py,sha256=Uz6zEeaJMcbvF3S0W0qmLI_uWsZsaSspHKNzuAMrasg,4069
24
+ pixeltable/exec/data_row_batch.py,sha256=1IDYHBkSQ60dwOnAGnS-Wpp3AsnbMqKcY40zUT7ku-Q,3392
25
+ pixeltable/exec/exec_context.py,sha256=E82Q2bJMJ1ulud5L5D9dh2Z8vEUQ659SgT614YKDO34,924
26
+ pixeltable/exec/exec_node.py,sha256=Hji5NCPHfa50IWyjladXrBm4I0zseV7AV4cVdx0Q8Ew,2170
27
+ pixeltable/exec/expr_eval_node.py,sha256=fEzbeZ0J-kylRQ2M0nSlUeLFRTHlwNzlvBo1yqWQ2rg,10856
28
+ pixeltable/exec/in_memory_data_node.py,sha256=SNM2AbMQSjmGDWMNJUf_5MmlXWE3P80lsuUjNfzQckA,3171
29
+ pixeltable/exec/media_validation_node.py,sha256=OKfRyKpcn7AZdACy_HD4NsDC87ZfNFs1tdrQz2NiIVw,1514
30
+ pixeltable/exec/sql_scan_node.py,sha256=s2PVls7gfSL0zQsdDWz8dC7MAE6KWeV_EDBCilx8Ros,10250
31
+ pixeltable/exprs/__init__.py,sha256=7dwrdk-NpF66OT-m5yNtFEhq-o1T476dnXHjluw2K1s,951
32
+ pixeltable/exprs/arithmetic_expr.py,sha256=sWBYCBKI6IHj9ASwDcm2BlkQ5gleVtKtmpiPvzFNBJM,4386
33
+ pixeltable/exprs/array_slice.py,sha256=VmWc6iFusrM85MjyEBBCfXG1Jnt8-Gr6-J88BXxNoOE,2131
34
+ pixeltable/exprs/column_property_ref.py,sha256=0PHiBys0fxe2LgjaMId5UHob4E-ZggyPLnnW41RgA0E,2706
35
+ pixeltable/exprs/column_ref.py,sha256=t_iJzai-x1Ds2ca3u5Qh3lzBqidP23e80Y7KcO_BDkA,5333
36
+ pixeltable/exprs/comparison.py,sha256=rAlGUF0AuzkYGspewJPu-6aaQZa4dVMJYGbMwqKyBIc,2964
37
+ pixeltable/exprs/compound_predicate.py,sha256=Gh22MKi625m5A_RunVRd-a1XFi-fitikqBVz2VNXKrs,3830
38
+ pixeltable/exprs/data_row.py,sha256=2kGnZhDna4bkgzb2y9iDnkLFe8lXSk59QAf9zW2Z-Y0,8278
39
+ pixeltable/exprs/expr.py,sha256=VYo7CqZJLb9Rsna4FbMBy6_KAZdbUy1oh6AmORpSUGw,24190
40
+ pixeltable/exprs/expr_set.py,sha256=Q64Q2yI0CTq2Ma_E-BUYlMotSstVuMm4OFZnBCedHRk,1222
41
+ pixeltable/exprs/function_call.py,sha256=JO0QwolyI60aG3t0zCqAxsaRWacvw6V6adNtY5WbyTo,17207
42
+ pixeltable/exprs/globals.py,sha256=liPgUTccTkyDRs4kG2r9ehRkwGZERmrCSJDZRdJoMqk,1537
43
+ pixeltable/exprs/image_member_access.py,sha256=KSYdTIaLh53dNRjv3SJFchPMPo7o5diJSQkV1NsyB4Y,3547
44
+ pixeltable/exprs/in_predicate.py,sha256=burxrBCH1MXqU-wrNWJvD0PRGzJdWy85intOSftQK54,3696
45
+ pixeltable/exprs/inline_array.py,sha256=293WuUEhYXrcp8-AnPDVIWQBPQMrPviB88A619Ls_Es,4499
46
+ pixeltable/exprs/inline_dict.py,sha256=TWYokJ14Nq-evODcYFVO471WSEDbz6cJqIdRb2PkbZQ,3885
47
+ pixeltable/exprs/is_null.py,sha256=nvpOXtQj1UeYJpkCWzbaGuQElzrA2HSG3XNQugOv-pw,1041
48
+ pixeltable/exprs/json_mapper.py,sha256=I60VNgus64ai80gnFCIsRn0VRWYXMkqH5VNvnATsN9s,4559
49
+ pixeltable/exprs/json_path.py,sha256=Wz_5zFsyc9TPhsSbsDjDmQ3Nb0uVIwMCx5nh-cQYBiE,6526
50
+ pixeltable/exprs/literal.py,sha256=5NNza-WL1dd3hNznwwkr_yAcTGXSIRYUszGfy30lruI,2396
51
+ pixeltable/exprs/object_ref.py,sha256=eTcx84aWRI59fIiGvbdv3_cfL0XW4xEFQ4lwpLpJkM8,1250
52
+ pixeltable/exprs/predicate.py,sha256=OSDgjfSqiK7J_5GZMUXMvjfyomKEGi0JNxeB073SGXw,1859
53
+ pixeltable/exprs/row_builder.py,sha256=cpQa7GHR2dZYxhCAwZBfz-MqO0oP-NS44mAYoVUOt7A,15662
54
+ pixeltable/exprs/rowid_ref.py,sha256=74w4rEy21YysTVbyKNc3op-pYFqDAx8VJdtl7ZPpxHs,4268
55
+ pixeltable/exprs/similarity_expr.py,sha256=LERVkFU8BwIi_S9IhAKXdFJSizJ2wI_0uN4_1AMZb1c,2664
56
+ pixeltable/exprs/type_cast.py,sha256=JMg8p1qYoFfiAXfJPSbTEnfrK7lRO_JMaqlPHOrhNQU,1793
57
+ pixeltable/exprs/variable.py,sha256=Kg_O4ytcHYZFijIyMHYBJn063cTKU1-YE583FAz8Qaw,1361
58
+ pixeltable/ext/__init__.py,sha256=0uugfuME1FybVo-MdxaVNGagRjhcvNTnv5MZUem6Cyo,269
59
+ pixeltable/ext/functions/yolox.py,sha256=LwrOtXMT57AP6-IkmRZ_12yN5-EiFRpTuh4Sexm8x24,3131
60
+ pixeltable/func/__init__.py,sha256=LCB5iB2aZyMrX-hn_oNBYnB1SE60t50hE23av_v2F50,348
61
+ pixeltable/func/aggregate_function.py,sha256=nEZ3WuVx3oabVK8yvqq6NNneI9USOkB8bL7etwQCUh4,9356
62
+ pixeltable/func/callable_function.py,sha256=nEEmXFvd8TW9TBPbDnC3q8phj9ARokAsB-OJ1_hTkGo,4612
63
+ pixeltable/func/expr_template_function.py,sha256=r0ML3IVGDgGM-7KtutnwnHBCmcDMfpblrJugh26A7Uc,4266
64
+ pixeltable/func/function.py,sha256=fANPfafLwY0Mq6CF21VYbuF-hRxxsPLHn5waoj1mOGY,5611
65
+ pixeltable/func/function_registry.py,sha256=1ibSQxEPm3Zd3r497vSlckQiDG9sfCnyJx3zcSm9t7c,11456
66
+ pixeltable/func/globals.py,sha256=sEwn6lGgHMp6VQORb_P5qRd_-Q2_bUSqvqM9-XPN_ec,1483
67
+ pixeltable/func/nos_function.py,sha256=HzIKK4XjTo1E6pML-EbhuX3u_LYibFWUuTkIxoIih7c,9650
68
+ pixeltable/func/signature.py,sha256=erOPFuSuaxkXnRyFd3nCYLuprUWcYFox3Hk3ZKUPWfM,6697
69
+ pixeltable/func/udf.py,sha256=92v3ArcZShR5D5xVWm5XB8HumCrPgc7frUrbu1yEPyo,6484
70
+ pixeltable/functions/__init__.py,sha256=uO-XB4QUbx3Jjs9GoaTXoJY2jn0AuXTL32YLkL_3_CI,3297
71
+ pixeltable/functions/eval.py,sha256=_2FANDJqwtIDzTxtcKc0Yacf7b4LTAjyy2fPDw1FG_s,8404
72
+ pixeltable/functions/fireworks.py,sha256=e_rCITg18yNndNI8TJPXRSN6DR0hYWT-_dUavoPuyfc,908
73
+ pixeltable/functions/huggingface.py,sha256=-a679an4nQyHChgQvvsfIoYGMQ_AfDmKpg2Ifc4FuV8,6458
74
+ pixeltable/functions/image.py,sha256=xR_S_0BuX6Ycc5E366GpOfP0JptD7beQwHE_fLl8ZVM,431
75
+ pixeltable/functions/openai.py,sha256=yvlxRd-9ViC4osJH0YWu18CuX83__NPPUVazXM3kJ8o,7972
76
+ pixeltable/functions/pil/image.py,sha256=6eNdMy2lZliFb8Lw12aBRUaShH07VEsFmhHSG21Jjt4,5992
77
+ pixeltable/functions/string.py,sha256=RYOgZwifjC943YloEMi3PdflnjFqOYB2FddrUvzgtXs,516
78
+ pixeltable/functions/together.py,sha256=HeiLQm0GCSgv5Jvdmw_Bqd7vKRBx-r6UazdseoEKMVg,4173
79
+ pixeltable/functions/util.py,sha256=djVqro_W5M_jUgYWzZZaXXH3lWaAWj6q-hrpzFl_Ko8,1860
80
+ pixeltable/functions/video.py,sha256=WZF4G3tV-_LfRQHUinXe_rnu1-4N68Ht60JCR_s7Bew,2403
81
+ pixeltable/globals.py,sha256=HWuz_erzAlBLkAYRqTJKphonSDLdNBTm1ZvVcxeFtwU,13606
82
+ pixeltable/index/__init__.py,sha256=tlJENOzEq6p_8xu-nX1mN4Zt9asw4481Znl5ZXYIKwc,72
83
+ pixeltable/index/base.py,sha256=MM8jLlr68e9M_R27EVsNxC7W7OVay27TOrnxrOlXz2s,1431
84
+ pixeltable/index/embedding_index.py,sha256=jxCTmW-KSNDNbFHbkQHYPI-CKTA_b6rTETH2t_qEFvM,7565
85
+ pixeltable/io/__init__.py,sha256=ejAAeWC8gIvNVxsOj7yNl4-3NHileGm-FKar9xvCy48,148
86
+ pixeltable/io/hf_datasets.py,sha256=h5M1NkXOvEU8kaeT3AON1A18Vmhnc1lVo5a3TZ5AAic,8004
87
+ pixeltable/io/pandas.py,sha256=cDHUDW2CGiBbsEJB9zE5vkXopTKxDdI-CZxNcp0OnIk,6478
88
+ pixeltable/io/parquet.py,sha256=Z1b92gsPeCBf4P9_jgWWHAEHtu51nhuC8nSJgoKiywQ,8150
89
+ pixeltable/iterators/__init__.py,sha256=kokLguXBY_nxBTqUiXZVvCxTv-vGsX4cK8tgIbsW5G8,108
90
+ pixeltable/iterators/base.py,sha256=4vss-RUq_L7ZQx9o99jZvRtFqPjtVXdwsuPtZ4JW_4s,1676
91
+ pixeltable/iterators/document.py,sha256=KmnrBJ7W39Xknj_pna7H--HbNztPmYFAleGhk9qsegY,19318
92
+ pixeltable/iterators/video.py,sha256=K39ZAIMVvqzGkE30gF2CAbIOOgoJnlBpmIPl4AnWbmY,3474
93
+ pixeltable/metadata/__init__.py,sha256=rBX4sIEfUlv11hDqgAOUl067l--zEeu-HQuGCTRZrfM,2227
94
+ pixeltable/metadata/converters/convert_10.py,sha256=0mSGCn7vqtef63riPi9msUaaUvsSQIj-NFj9QFDYPdA,733
95
+ pixeltable/metadata/converters/convert_12.py,sha256=g9rHTcKlDQZbM3_k4eBv0FBdWmQXHWCnMwx1_l6KpMI,107
96
+ pixeltable/metadata/converters/convert_13.py,sha256=FEgOH5PKf05xVoCaioDDDHOSuoWPyBzodojmsSMMZ5U,1366
97
+ pixeltable/metadata/schema.py,sha256=uuk3rzCpYr99PzEO1pIXe8nMaOoTJtwRfhnqgQ_MdDs,8335
98
+ pixeltable/plan.py,sha256=isb2-ECB3TwvHxZIR9lEKZ0wRKTCvRFp9NQDYhULxdI,32342
99
+ pixeltable/store.py,sha256=Mau3tRfXn6z1J3rzvtU3R4_-UjD-TMTv1FK8OjPMqp0,19394
100
+ pixeltable/tool/create_test_db_dump.py,sha256=yI62rFk7StF1cI8BKN1_hf6mkB6e4ndJH95gXeJOQFA,6847
101
+ pixeltable/tool/create_test_video.py,sha256=OLfccymYReIpzE8osZn4rQvLXxxiPC_l0vc06U74hVM,2899
102
+ pixeltable/type_system.py,sha256=DdI6g-ouqny8PdokEClxKwEwqjbWFDAxNrhYGh7pQLo,29224
103
+ pixeltable/utils/__init__.py,sha256=UYlrf6TIWJT0g-Hac0b34-dEk478B5Qx8dGco34YlIk,439
104
+ pixeltable/utils/arrow.py,sha256=83_7aG5UR2qtTktw_otLkQs-RQbLk0VVM0JLJkbweNU,3692
105
+ pixeltable/utils/clip.py,sha256=HXXWFBJXW9XysdMk9_3hP1V1S-3B8Hwd5rNMbJFjjnI,720
106
+ pixeltable/utils/coco.py,sha256=mk1cxjKYQC0ABm2ZQ9SNu9MvBPECmmKvnASpxnFXdL0,5604
107
+ pixeltable/utils/documents.py,sha256=Q7e5U2Hk0go83MdKzD_MIiMscwbcFsLMgRw2IU_vQF4,2213
108
+ pixeltable/utils/filecache.py,sha256=UoNONG2VaAc2IBB0e3sQdsvyOPOes2XSDc5_CsA4qek,7839
109
+ pixeltable/utils/help.py,sha256=cCnxJ4VP9MJ57iDqExmnDcM-JG3a1lw_q7g-D7bpSVI,252
110
+ pixeltable/utils/http_server.py,sha256=WQ5ILMzlz4TlwI9j5YqAPgEZyhrN1GytMNDbLD9occk,2422
111
+ pixeltable/utils/media_store.py,sha256=x71wnJDZDHcdd13VCfL4AkHQ6IJB41gNA-zBvXJwFos,3116
112
+ pixeltable/utils/pytorch.py,sha256=BR4tgfUWw-2rwWTOgzXj5qdMBpe1Arpp5SK4ax6jjpk,3483
113
+ pixeltable/utils/s3.py,sha256=rkanuhk9DWvSfmbOLQW1j1Iov4sl2KhxGGKN-AJ8LSE,432
114
+ pixeltable/utils/sql.py,sha256=5n5_OmXAGtqFdL6z5XvgnU-vlx6Ba6f1WJrO1ZwUle8,765
115
+ pixeltable/utils/transactional_directory.py,sha256=UGzCrGtLR3hEEf8sYGuWBzLVFAEQml3vdIavigWeTBM,1349
116
+ pixeltable-0.2.6.dist-info/LICENSE,sha256=0UNMmwuqWPC0xDY1NWMm4uNJ2_MyA1pnTNRgQTvuBiQ,746
117
+ pixeltable-0.2.6.dist-info/METADATA,sha256=BccXbmH76wNKX3D9Un4AZ28-E-blrldlrOamu2XdLpg,6317
118
+ pixeltable-0.2.6.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
119
+ pixeltable-0.2.6.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.8.1
2
+ Generator: poetry-core 1.9.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any