cocoindex 0.2.5__cp311-abi3-manylinux_2_28_x86_64.whl → 0.2.7__cp311-abi3-manylinux_2_28_x86_64.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/_engine.abi3.so +0 -0
- cocoindex/cli.py +29 -3
- cocoindex/flow.py +14 -4
- cocoindex/subprocess_exec.py +36 -12
- {cocoindex-0.2.5.dist-info → cocoindex-0.2.7.dist-info}/METADATA +3 -1
- {cocoindex-0.2.5.dist-info → cocoindex-0.2.7.dist-info}/RECORD +9 -9
- cocoindex-0.2.7.dist-info/licenses/THIRD_PARTY_NOTICES.html +12665 -0
- cocoindex/tests/conftest.py +0 -38
- {cocoindex-0.2.5.dist-info → cocoindex-0.2.7.dist-info}/WHEEL +0 -0
- {cocoindex-0.2.5.dist-info → cocoindex-0.2.7.dist-info}/entry_points.txt +0 -0
cocoindex/_engine.abi3.so
CHANGED
Binary file
|
cocoindex/cli.py
CHANGED
@@ -363,6 +363,13 @@ def drop(app_target: str | None, flow_name: tuple[str, ...], force: bool) -> Non
|
|
363
363
|
default=False,
|
364
364
|
help="Continuously watch changes from data sources and apply to the target index.",
|
365
365
|
)
|
366
|
+
@click.option(
|
367
|
+
"--reexport",
|
368
|
+
is_flag=True,
|
369
|
+
show_default=True,
|
370
|
+
default=False,
|
371
|
+
help="Reexport to targets even if there's no change.",
|
372
|
+
)
|
366
373
|
@click.option(
|
367
374
|
"--setup",
|
368
375
|
is_flag=True,
|
@@ -389,6 +396,7 @@ def drop(app_target: str | None, flow_name: tuple[str, ...], force: bool) -> Non
|
|
389
396
|
def update(
|
390
397
|
app_flow_specifier: str,
|
391
398
|
live: bool,
|
399
|
+
reexport: bool,
|
392
400
|
setup: bool, # pylint: disable=redefined-outer-name
|
393
401
|
force: bool,
|
394
402
|
quiet: bool,
|
@@ -408,7 +416,11 @@ def update(
|
|
408
416
|
fg="yellow",
|
409
417
|
)
|
410
418
|
|
411
|
-
options = flow.FlowLiveUpdaterOptions(
|
419
|
+
options = flow.FlowLiveUpdaterOptions(
|
420
|
+
live_mode=live,
|
421
|
+
reexport_targets=reexport,
|
422
|
+
print_stats=not quiet,
|
423
|
+
)
|
412
424
|
if flow_name is None:
|
413
425
|
if setup:
|
414
426
|
_setup_flows(
|
@@ -519,6 +531,13 @@ def evaluate(
|
|
519
531
|
default=False,
|
520
532
|
help="Automatically setup backends for the flow if it's not setup yet.",
|
521
533
|
)
|
534
|
+
@click.option(
|
535
|
+
"--reexport",
|
536
|
+
is_flag=True,
|
537
|
+
show_default=True,
|
538
|
+
default=False,
|
539
|
+
help="Reexport to targets even if there's no change.",
|
540
|
+
)
|
522
541
|
@click.option(
|
523
542
|
"-f",
|
524
543
|
"--force",
|
@@ -548,6 +567,7 @@ def server(
|
|
548
567
|
address: str | None,
|
549
568
|
live_update: bool,
|
550
569
|
setup: bool, # pylint: disable=redefined-outer-name
|
570
|
+
reexport: bool,
|
551
571
|
force: bool,
|
552
572
|
quiet: bool,
|
553
573
|
cors_origin: str | None,
|
@@ -571,6 +591,7 @@ def server(
|
|
571
591
|
cors_local,
|
572
592
|
live_update,
|
573
593
|
setup,
|
594
|
+
reexport,
|
574
595
|
force,
|
575
596
|
quiet,
|
576
597
|
)
|
@@ -619,6 +640,7 @@ def _run_server(
|
|
619
640
|
cors_local: int | None = None,
|
620
641
|
live_update: bool = False,
|
621
642
|
run_setup: bool = False,
|
643
|
+
reexport: bool = False,
|
622
644
|
force: bool = False,
|
623
645
|
quiet: bool = False,
|
624
646
|
) -> None:
|
@@ -652,8 +674,12 @@ def _run_server(
|
|
652
674
|
|
653
675
|
click.secho("Press Ctrl+C to stop the server.", fg="yellow")
|
654
676
|
|
655
|
-
if live_update:
|
656
|
-
options = flow.FlowLiveUpdaterOptions(
|
677
|
+
if live_update or reexport:
|
678
|
+
options = flow.FlowLiveUpdaterOptions(
|
679
|
+
live_mode=live_update,
|
680
|
+
reexport_targets=reexport,
|
681
|
+
print_stats=not quiet,
|
682
|
+
)
|
657
683
|
asyncio.run_coroutine_threadsafe(
|
658
684
|
_update_all_flows_with_hint_async(options), execution_context.event_loop
|
659
685
|
)
|
cocoindex/flow.py
CHANGED
@@ -563,9 +563,14 @@ class FlowBuilder:
|
|
563
563
|
class FlowLiveUpdaterOptions:
|
564
564
|
"""
|
565
565
|
Options for live updating a flow.
|
566
|
+
|
567
|
+
- live_mode: Whether to perform live update for data sources with change capture mechanisms.
|
568
|
+
- reexport_targets: Whether to reexport to targets even if there's no change.
|
569
|
+
- print_stats: Whether to print stats during update.
|
566
570
|
"""
|
567
571
|
|
568
572
|
live_mode: bool = True
|
573
|
+
reexport_targets: bool = False
|
569
574
|
print_stats: bool = False
|
570
575
|
|
571
576
|
|
@@ -759,20 +764,25 @@ class Flow:
|
|
759
764
|
"""
|
760
765
|
return self._full_name
|
761
766
|
|
762
|
-
def update(self) -> _engine.IndexUpdateInfo:
|
767
|
+
def update(self, /, *, reexport_targets: bool = False) -> _engine.IndexUpdateInfo:
|
763
768
|
"""
|
764
769
|
Update the index defined by the flow.
|
765
770
|
Once the function returns, the index is fresh up to the moment when the function is called.
|
766
771
|
"""
|
767
|
-
return execution_context.run(
|
772
|
+
return execution_context.run(
|
773
|
+
self.update_async(reexport_targets=reexport_targets)
|
774
|
+
)
|
768
775
|
|
769
|
-
async def update_async(
|
776
|
+
async def update_async(
|
777
|
+
self, /, *, reexport_targets: bool = False
|
778
|
+
) -> _engine.IndexUpdateInfo:
|
770
779
|
"""
|
771
780
|
Update the index defined by the flow.
|
772
781
|
Once the function returns, the index is fresh up to the moment when the function is called.
|
773
782
|
"""
|
774
783
|
async with FlowLiveUpdater(
|
775
|
-
self,
|
784
|
+
self,
|
785
|
+
FlowLiveUpdaterOptions(live_mode=False, reexport_targets=reexport_targets),
|
776
786
|
) as updater:
|
777
787
|
await updater.wait_async()
|
778
788
|
return updater.update_stats()
|
cocoindex/subprocess_exec.py
CHANGED
@@ -134,24 +134,43 @@ def _start_parent_watchdog(
|
|
134
134
|
This runs in a background daemon thread so it never blocks pool work.
|
135
135
|
"""
|
136
136
|
|
137
|
+
import psutil # type: ignore
|
138
|
+
|
139
|
+
if parent_pid is None:
|
140
|
+
parent_pid = os.getppid()
|
141
|
+
|
142
|
+
try:
|
143
|
+
p = psutil.Process(parent_pid)
|
144
|
+
# Cache create_time to defeat PID reuse.
|
145
|
+
created = p.create_time()
|
146
|
+
except psutil.Error:
|
147
|
+
# Parent already gone or not accessible
|
148
|
+
os._exit(1)
|
149
|
+
|
137
150
|
def _watch() -> None:
|
138
151
|
while True:
|
139
|
-
# If PPID changed (parent died and we were reparented), exit.
|
140
|
-
if os.getppid() != parent_pid:
|
141
|
-
os._exit(1)
|
142
|
-
|
143
|
-
# Best-effort liveness probe in case PPID was reused.
|
144
152
|
try:
|
145
|
-
|
146
|
-
|
153
|
+
# is_running() + same create_time => same process and still alive
|
154
|
+
if not (p.is_running() and p.create_time() == created):
|
155
|
+
os._exit(1)
|
156
|
+
except psutil.NoSuchProcess:
|
147
157
|
os._exit(1)
|
148
|
-
|
149
158
|
time.sleep(interval_seconds)
|
150
159
|
|
151
160
|
threading.Thread(target=_watch, name="parent-watchdog", daemon=True).start()
|
152
161
|
|
153
162
|
|
154
163
|
def _subprocess_init(user_apps: list[str], parent_pid: int) -> None:
|
164
|
+
import signal
|
165
|
+
import faulthandler
|
166
|
+
|
167
|
+
faulthandler.enable()
|
168
|
+
# Ignore SIGINT in the subprocess on best-effort basis.
|
169
|
+
try:
|
170
|
+
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
171
|
+
except Exception:
|
172
|
+
pass
|
173
|
+
|
155
174
|
_start_parent_watchdog(parent_pid)
|
156
175
|
|
157
176
|
# In case any user app is already in this subprocess, e.g. the subprocess is forked, we need to avoid loading it again.
|
@@ -193,10 +212,15 @@ _SUBPROC_EXECUTORS: dict[bytes, _ExecutorEntry] = {}
|
|
193
212
|
|
194
213
|
def _call_method(method: Callable[..., Any], *args: Any, **kwargs: Any) -> Any:
|
195
214
|
"""Run an awaitable/coroutine to completion synchronously, otherwise return as-is."""
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
215
|
+
try:
|
216
|
+
if asyncio.iscoroutinefunction(method):
|
217
|
+
return asyncio.run(method(*args, **kwargs))
|
218
|
+
else:
|
219
|
+
return method(*args, **kwargs)
|
220
|
+
except Exception as e:
|
221
|
+
raise RuntimeError(
|
222
|
+
f"Error calling method `{method.__name__}` from subprocess"
|
223
|
+
) from e
|
200
224
|
|
201
225
|
|
202
226
|
def _get_or_create_entry(key_bytes: bytes) -> _ExecutorEntry:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: cocoindex
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.7
|
4
4
|
Classifier: Development Status :: 3 - Alpha
|
5
5
|
Classifier: License :: OSI Approved :: Apache Software License
|
6
6
|
Classifier: Operating System :: OS Independent
|
@@ -21,6 +21,7 @@ Requires-Dist: rich>=14.0.0
|
|
21
21
|
Requires-Dist: python-dotenv>=1.1.0
|
22
22
|
Requires-Dist: watchfiles>=1.1.0
|
23
23
|
Requires-Dist: numpy>=1.23.2
|
24
|
+
Requires-Dist: psutil>=7.0.0
|
24
25
|
Requires-Dist: pytest ; extra == 'dev'
|
25
26
|
Requires-Dist: pytest-asyncio ; extra == 'dev'
|
26
27
|
Requires-Dist: ruff ; extra == 'dev'
|
@@ -34,6 +35,7 @@ Provides-Extra: dev
|
|
34
35
|
Provides-Extra: embeddings
|
35
36
|
Provides-Extra: colpali
|
36
37
|
Provides-Extra: all
|
38
|
+
License-File: THIRD_PARTY_NOTICES.html
|
37
39
|
Summary: With CocoIndex, users declare the transformation, CocoIndex creates & maintains an index, and keeps the derived index up to date based on source update, with minimal computation and changes.
|
38
40
|
Keywords: indexing,real-time,incremental,pipeline,search,ai,etl,rag,dataflow,context-engineering
|
39
41
|
Author-email: CocoIndex <cocoindex.io@gmail.com>
|
@@ -1,12 +1,13 @@
|
|
1
|
-
cocoindex-0.2.
|
2
|
-
cocoindex-0.2.
|
3
|
-
cocoindex-0.2.
|
1
|
+
cocoindex-0.2.7.dist-info/METADATA,sha256=MvtUzkoSmDgJRFLhsratRoLuH0Tu_ijCV4N3aiT1-58,12998
|
2
|
+
cocoindex-0.2.7.dist-info/WHEEL,sha256=IG-K_sumA04dNIpy5J1b3kZo_HELEjvxxDWHD32zTgo,107
|
3
|
+
cocoindex-0.2.7.dist-info/entry_points.txt,sha256=_NretjYVzBdNTn7dK-zgwr7YfG2afz1u1uSE-5bZXF8,46
|
4
|
+
cocoindex-0.2.7.dist-info/licenses/THIRD_PARTY_NOTICES.html,sha256=LoD8IOKM2beOhYqtdnA9YRt6xoXzKr_73KFP9RYqjBQ,716358
|
4
5
|
cocoindex/__init__.py,sha256=sLpSVO5Cotgn_82lawxvXnaqfa-qj33rytWBAe2MTtU,2201
|
5
|
-
cocoindex/_engine.abi3.so,sha256=
|
6
|
+
cocoindex/_engine.abi3.so,sha256=E43aWdSi-OPwrFUezQ3UN7PKgTqkWhah2yZvAb-sFuo,72588696
|
6
7
|
cocoindex/auth_registry.py,sha256=PE1-kVkcyC1G2C_V7b1kvYzeq73OFQehWKQP7ln7fJ8,1478
|
7
|
-
cocoindex/cli.py,sha256=
|
8
|
+
cocoindex/cli.py,sha256=laLLHtEQvEt7Ua4xulsWEI_dH5IpHiaXyTWY8p1VF_c,21665
|
8
9
|
cocoindex/convert.py,sha256=Eh9Co37BtW_PK3Oi-pFEiFt8cc_6g7XLcurV-NeH6GU,22090
|
9
|
-
cocoindex/flow.py,sha256=
|
10
|
+
cocoindex/flow.py,sha256=wKT_RWeB9_sm764aNrOl2XU-RJIu4EK_sIkjcyZI8jA,37669
|
10
11
|
cocoindex/functions.py,sha256=09erNt3WbzY9l1KER-akBF2O5-6xEahV2ORBECaL6yk,12260
|
11
12
|
cocoindex/index.py,sha256=j93B9jEvvLXHtpzKWL88SY6wCGEoPgpsQhEGHlyYGFg,540
|
12
13
|
cocoindex/lib.py,sha256=f--9dAYd84CZosbDZqNW0oGbBLsY3dXiUTR1VrfQ_QY,817
|
@@ -17,10 +18,9 @@ cocoindex/runtime.py,sha256=povilB3HH3y1JF-yxKwU-pD8n2WnAqyQxIgvXXHNc60,1080
|
|
17
18
|
cocoindex/setting.py,sha256=cuudZ2uJvS48wh-rDToPAUN7-KMjlyQ-0hWhkHMIx4U,5282
|
18
19
|
cocoindex/setup.py,sha256=7uIHKN4FOCuoidPXcKyGTrkqpkl9luL49-6UcnMxYzw,3068
|
19
20
|
cocoindex/sources.py,sha256=FYz7cWYasLGDaYoIEQ1dF2uprgUETHWsTIrIS7n6pQE,3188
|
20
|
-
cocoindex/subprocess_exec.py,sha256=
|
21
|
+
cocoindex/subprocess_exec.py,sha256=r1xO84uek4VP4I6i87JMwsH5xFm3vKW0ABvgn0jskt4,10088
|
21
22
|
cocoindex/targets.py,sha256=Nfh_tpFd1goTnS_cxBjIs4j9zl3Z4Z1JomAQ1dl3Sic,2796
|
22
23
|
cocoindex/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
23
|
-
cocoindex/tests/conftest.py,sha256=Q1ev90H_6zncEL0nlzgd4idIaE6OQW_8cMf05V-Wgec,1054
|
24
24
|
cocoindex/tests/test_convert.py,sha256=UsQDuz7qukT9UAU5LBv3atNTqdUVc6uW8lrmLA7ys_w,50207
|
25
25
|
cocoindex/tests/test_optional_database.py,sha256=snAmkNa6wtOSaxoZE1HgjvL5v_ylitt3Jt_9df4Cgdc,8506
|
26
26
|
cocoindex/tests/test_transform_flow.py,sha256=G69w-n-vnCTo3r9hVIk2lJNAQEkGUA7PZfHsXna3oS0,6030
|
@@ -30,4 +30,4 @@ cocoindex/typing.py,sha256=lEQYIzAGVKQp6RnhyeopY9Q7xEED7yQj3ZMxvTPblV8,14200
|
|
30
30
|
cocoindex/user_app_loader.py,sha256=bc3Af-gYRxJ9GpObtpjegZY855oQBCv5FGkrkWV2yGY,1873
|
31
31
|
cocoindex/utils.py,sha256=hUhX-XV6XGCtJSEIpBOuDv6VvqImwPlgBxztBTw7u0U,598
|
32
32
|
cocoindex/validation.py,sha256=PZnJoby4sLbsmPv9fOjOQXuefjfZ7gmtsiTGU8SH-tc,3090
|
33
|
-
cocoindex-0.2.
|
33
|
+
cocoindex-0.2.7.dist-info/RECORD,,
|