cocoindex 0.1.82__cp313-cp313t-manylinux_2_28_aarch64.whl → 0.1.83__cp313-cp313t-manylinux_2_28_aarch64.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.
cocoindex/flow.py CHANGED
@@ -105,18 +105,26 @@ def _spec_kind(spec: Any) -> str:
105
105
 
106
106
  def _transform_helper(
107
107
  flow_builder_state: _FlowBuilderState,
108
- fn_spec: FunctionSpec,
108
+ fn_spec: FunctionSpec | Callable[..., Any],
109
109
  transform_args: list[tuple[Any, str | None]],
110
110
  name: str | None = None,
111
111
  ) -> DataSlice[Any]:
112
- if not isinstance(fn_spec, FunctionSpec):
112
+ if isinstance(fn_spec, FunctionSpec):
113
+ kind = _spec_kind(fn_spec)
114
+ spec = fn_spec
115
+ elif callable(fn_spec) and (
116
+ op_kind := getattr(fn_spec, "__cocoindex_op_kind__", None)
117
+ ):
118
+ kind = op_kind
119
+ spec = op.EmptyFunctionSpec()
120
+ else:
113
121
  raise ValueError("transform() can only be called on a CocoIndex function")
114
122
 
115
123
  return _create_data_slice(
116
124
  flow_builder_state,
117
125
  lambda target_scope, name: flow_builder_state.engine_flow_builder.transform(
118
- _spec_kind(fn_spec),
119
- dump_engine_object(fn_spec),
126
+ kind,
127
+ dump_engine_object(spec),
120
128
  transform_args,
121
129
  target_scope,
122
130
  flow_builder_state.field_name_builder.build_name(
@@ -245,7 +253,7 @@ class DataSlice(Generic[T]):
245
253
  f(scope)
246
254
 
247
255
  def transform(
248
- self, fn_spec: op.FunctionSpec, *args: Any, **kwargs: Any
256
+ self, fn_spec: op.FunctionSpec | Callable[..., Any], *args: Any, **kwargs: Any
249
257
  ) -> DataSlice[Any]:
250
258
  """
251
259
  Apply a function to the data slice.
@@ -513,7 +521,7 @@ class FlowBuilder:
513
521
  )
514
522
 
515
523
  def transform(
516
- self, fn_spec: FunctionSpec, *args: Any, **kwargs: Any
524
+ self, fn_spec: FunctionSpec | Callable[..., Any], *args: Any, **kwargs: Any
517
525
  ) -> DataSlice[Any]:
518
526
  """
519
527
  Apply a function to inputs, returning a DataSlice.
cocoindex/op.py CHANGED
@@ -388,53 +388,39 @@ def executor_class(**args: Any) -> Callable[[type], type]:
388
388
  return _inner
389
389
 
390
390
 
391
- class _EmptyFunctionSpec(FunctionSpec):
391
+ class EmptyFunctionSpec(FunctionSpec):
392
392
  pass
393
393
 
394
394
 
395
395
  class _SimpleFunctionExecutor:
396
- spec: Any
396
+ spec: Callable[..., Any]
397
397
 
398
398
  def prepare(self) -> None:
399
- self.__call__ = self.spec.__call__
399
+ self.__call__ = staticmethod(self.spec)
400
400
 
401
401
 
402
- def function(**args: Any) -> Callable[[Callable[..., Any]], FunctionSpec]:
402
+ def function(**args: Any) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
403
403
  """
404
404
  Decorate a function to provide a function for an op.
405
405
  """
406
406
  op_args = OpArgs(**args)
407
407
 
408
- def _inner(fn: Callable[..., Any]) -> FunctionSpec:
408
+ def _inner(fn: Callable[..., Any]) -> Callable[..., Any]:
409
409
  # Convert snake case to camel case.
410
- op_name = "".join(word.capitalize() for word in fn.__name__.split("_"))
410
+ op_kind = "".join(word.capitalize() for word in fn.__name__.split("_"))
411
411
  sig = inspect.signature(fn)
412
- full_name = f"{fn.__module__}.{fn.__qualname__}"
413
-
414
- # An object that is both callable and can act as a FunctionSpec.
415
- class _CallableSpec(_EmptyFunctionSpec):
416
- __call__ = staticmethod(fn)
417
-
418
- def __reduce__(self) -> str | tuple[Any, ...]:
419
- return full_name
420
-
421
- _CallableSpec.__name__ = op_name
422
- _CallableSpec.__doc__ = fn.__doc__
423
- _CallableSpec.__qualname__ = fn.__qualname__
424
- _CallableSpec.__module__ = fn.__module__
425
- callable_spec = _CallableSpec()
426
-
412
+ fn.__cocoindex_op_kind__ = op_kind # type: ignore
427
413
  _register_op_factory(
428
414
  category=OpCategory.FUNCTION,
429
415
  expected_args=list(sig.parameters.items()),
430
416
  expected_return=sig.return_annotation,
431
417
  executor_factory=_SimpleFunctionExecutor,
432
- spec_loader=lambda: callable_spec,
433
- op_kind=op_name,
418
+ spec_loader=lambda: fn,
419
+ op_kind=op_kind,
434
420
  op_args=op_args,
435
421
  )
436
422
 
437
- return callable_spec
423
+ return fn
438
424
 
439
425
  return _inner
440
426
 
cocoindex/sources.py CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  from . import op
4
4
  from .auth_registry import TransientAuthEntryReference
5
+ from .setting import DatabaseConnectionSpec
5
6
  import datetime
6
7
 
7
8
 
@@ -67,3 +68,22 @@ class AzureBlob(op.SourceSpec):
67
68
 
68
69
  sas_token: TransientAuthEntryReference[str] | None = None
69
70
  account_access_key: TransientAuthEntryReference[str] | None = None
71
+
72
+
73
+ class Postgres(op.SourceSpec):
74
+ """Import data from a PostgreSQL table."""
75
+
76
+ _op_category = op.OpCategory.SOURCE
77
+
78
+ # Table name to read from (required)
79
+ table_name: str
80
+
81
+ # Database connection reference (optional - uses default if not provided)
82
+ database: TransientAuthEntryReference[DatabaseConnectionSpec] | None = None
83
+
84
+ # Optional: specific columns to include (if None, includes all columns)
85
+ included_columns: list[str] | None = None
86
+
87
+ # Optional: column name to use for ordinal tracking (for incremental updates)
88
+ # Should be a timestamp, serial, or other incrementing column
89
+ ordinal_column: str | None = None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cocoindex
3
- Version: 0.1.82
3
+ Version: 0.1.83
4
4
  Requires-Dist: click>=8.1.8
5
5
  Requires-Dist: rich>=14.0.0
6
6
  Requires-Dist: python-dotenv>=1.1.0
@@ -1,23 +1,23 @@
1
- cocoindex-0.1.82.dist-info/METADATA,sha256=totDI7Pxf_1q8U_5YRvAq0npG0A0loaeUpM7PeKvfkU,12188
2
- cocoindex-0.1.82.dist-info/WHEEL,sha256=zN8Ntfo1EySzcfoKOM6EUm6PKp3NH4KTsSh5OV_WgdA,110
3
- cocoindex-0.1.82.dist-info/entry_points.txt,sha256=_NretjYVzBdNTn7dK-zgwr7YfG2afz1u1uSE-5bZXF8,46
4
- cocoindex-0.1.82.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1
+ cocoindex-0.1.83.dist-info/METADATA,sha256=UDk1JdA2YJruSvFsxj-gg7LNr229159YhQ5JO1QfeyQ,12188
2
+ cocoindex-0.1.83.dist-info/WHEEL,sha256=zN8Ntfo1EySzcfoKOM6EUm6PKp3NH4KTsSh5OV_WgdA,110
3
+ cocoindex-0.1.83.dist-info/entry_points.txt,sha256=_NretjYVzBdNTn7dK-zgwr7YfG2afz1u1uSE-5bZXF8,46
4
+ cocoindex-0.1.83.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
5
5
  cocoindex/__init__.py,sha256=sLpSVO5Cotgn_82lawxvXnaqfa-qj33rytWBAe2MTtU,2201
6
- cocoindex/_engine.cpython-313t-aarch64-linux-gnu.so,sha256=fsQ5EJJbPXQ4ubQQt7_exqrze2eCIHKSd-lbOEF24Zg,69679656
6
+ cocoindex/_engine.cpython-313t-aarch64-linux-gnu.so,sha256=fUGVExPZCuanvaAG-HVjcezX2qLlnyLl5HEPANUGj1I,69796296
7
7
  cocoindex/auth_registry.py,sha256=PE1-kVkcyC1G2C_V7b1kvYzeq73OFQehWKQP7ln7fJ8,1478
8
8
  cocoindex/cli.py,sha256=8Q2D0gI_yHorxfFC7tzV96oJAR7PtTn_T4qWLorPPoM,20675
9
9
  cocoindex/convert.py,sha256=bf61K1gEYhZx05LQtV_-E7SDOUYpiYaHZtH8iZ1W_VE,21473
10
- cocoindex/flow.py,sha256=W0PjZ0vLQFEW6tvbblje85jnkz4Mn9B1_Z4_slUffYM,35981
10
+ cocoindex/flow.py,sha256=7133Z6QU4LF_GMV81AmkO_aGhfAQCStwOnMW7BABymU,36258
11
11
  cocoindex/functions.py,sha256=09erNt3WbzY9l1KER-akBF2O5-6xEahV2ORBECaL6yk,12260
12
12
  cocoindex/index.py,sha256=j93B9jEvvLXHtpzKWL88SY6wCGEoPgpsQhEGHlyYGFg,540
13
13
  cocoindex/lib.py,sha256=f--9dAYd84CZosbDZqNW0oGbBLsY3dXiUTR1VrfQ_QY,817
14
14
  cocoindex/llm.py,sha256=Pv_cdnRngTLtuLU9AUmS8izIHhcKVnuBNolC33f9BDI,851
15
- cocoindex/op.py,sha256=kdcWAOvvMxTVTinOZK6cVi8tY59G6VOdVuTV8fUJy0A,22714
15
+ cocoindex/op.py,sha256=w9CnrCEE6P5Voo2LDvMDlYPrBQuzNC5FfOHP6WF0Buw,22241
16
16
  cocoindex/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  cocoindex/runtime.py,sha256=povilB3HH3y1JF-yxKwU-pD8n2WnAqyQxIgvXXHNc60,1080
18
18
  cocoindex/setting.py,sha256=n5ipJ_uMFZBh5-Ib_gyjOqS_XPXsQwTFVYEuSAnoscg,5283
19
19
  cocoindex/setup.py,sha256=7uIHKN4FOCuoidPXcKyGTrkqpkl9luL49-6UcnMxYzw,3068
20
- cocoindex/sources.py,sha256=69COA4qbZDipzGYfXv-WJSmicFkA509xIShRGDh6A0A,2083
20
+ cocoindex/sources.py,sha256=o57FZARXaLKuQr4nKYLj9kxXBRX3cWEfDhFG3lldxoE,2779
21
21
  cocoindex/subprocess_exec.py,sha256=davnBvbw119NBaFX6s9IyHW9MTZyrYYuKYex0HManHY,7902
22
22
  cocoindex/targets.py,sha256=Nfh_tpFd1goTnS_cxBjIs4j9zl3Z4Z1JomAQ1dl3Sic,2796
23
23
  cocoindex/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -30,4 +30,4 @@ cocoindex/typing.py,sha256=qQ0ANF3iuQDeSqipHgL2SDiiXL2reTMUN0aj4ve_T0w,13359
30
30
  cocoindex/user_app_loader.py,sha256=o2n25y7CGw9Qrb-RN6tiNlv2YJ9YLM8NSMhJZjLhhKQ,1914
31
31
  cocoindex/utils.py,sha256=hUhX-XV6XGCtJSEIpBOuDv6VvqImwPlgBxztBTw7u0U,598
32
32
  cocoindex/validation.py,sha256=PZnJoby4sLbsmPv9fOjOQXuefjfZ7gmtsiTGU8SH-tc,3090
33
- cocoindex-0.1.82.dist-info/RECORD,,
33
+ cocoindex-0.1.83.dist-info/RECORD,,