pipelime-python 2.1.0__py3-none-any.whl → 2.3.0__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.
- pipelime/__init__.py +1 -1
- pipelime/cli/utils.py +4 -2
- pipelime/commands/piper.py +8 -3
- pipelime/piper/progress/listener/callbacks/loguru.py +79 -0
- pipelime/piper/progress/listener/factory.py +5 -2
- {pipelime_python-2.1.0.dist-info → pipelime_python-2.3.0.dist-info}/METADATA +4 -3
- {pipelime_python-2.1.0.dist-info → pipelime_python-2.3.0.dist-info}/RECORD +10 -9
- {pipelime_python-2.1.0.dist-info → pipelime_python-2.3.0.dist-info}/WHEEL +1 -1
- {pipelime_python-2.1.0.dist-info → pipelime_python-2.3.0.dist-info}/entry_points.txt +0 -0
- {pipelime_python-2.1.0.dist-info → pipelime_python-2.3.0.dist-info}/licenses/LICENSE +0 -0
pipelime/__init__.py
CHANGED
pipelime/cli/utils.py
CHANGED
|
@@ -816,7 +816,9 @@ def get_user_input(text: str) -> t.Any:
|
|
|
816
816
|
Returns:
|
|
817
817
|
The parsed user input.
|
|
818
818
|
"""
|
|
819
|
-
live
|
|
819
|
+
# if there is only one live, pause it to avoid messing the prompt
|
|
820
|
+
live_stack = get_console()._live_stack
|
|
821
|
+
live = live_stack[0] if len(live_stack) == 1 else None
|
|
820
822
|
if live is not None:
|
|
821
823
|
live.stop()
|
|
822
824
|
|
|
@@ -878,7 +880,7 @@ class PipelimeUserAppDir:
|
|
|
878
880
|
for i in reversed(range(1, cls.MAX_CHECKPOINTS)):
|
|
879
881
|
ckpt = base_ckpt.with_name(base_ckpt.name + f"-{i}")
|
|
880
882
|
if ckpt.exists():
|
|
881
|
-
ckpt.rename(base_ckpt.with_name(base_ckpt.name + f"-{i+1}"))
|
|
883
|
+
ckpt.rename(base_ckpt.with_name(base_ckpt.name + f"-{i + 1}"))
|
|
882
884
|
|
|
883
885
|
ckpt = base_ckpt.with_name(base_ckpt.name + "-1")
|
|
884
886
|
ckpt.mkdir(parents=True, exist_ok=False)
|
pipelime/commands/piper.py
CHANGED
|
@@ -25,11 +25,13 @@ class WatcherBackend(Enum):
|
|
|
25
25
|
|
|
26
26
|
RICH = "rich"
|
|
27
27
|
TQDM = "tqdm"
|
|
28
|
+
LOGURU = "loguru"
|
|
28
29
|
|
|
29
30
|
def listener_key(self) -> str:
|
|
30
31
|
return {
|
|
31
32
|
WatcherBackend.RICH: "RICH_TABLE",
|
|
32
33
|
WatcherBackend.TQDM: "TQDM_BARS",
|
|
34
|
+
WatcherBackend.LOGURU: "LOGURU",
|
|
33
35
|
}[self]
|
|
34
36
|
|
|
35
37
|
|
|
@@ -254,8 +256,10 @@ class RunCommandBase(GraphPortForwardingCommand):
|
|
|
254
256
|
|
|
255
257
|
PipelimeCommand._track_callback = DirectTrackCallback(callback)
|
|
256
258
|
|
|
257
|
-
# disable annoying logging
|
|
258
|
-
|
|
259
|
+
# disable annoying logging (only if we don't need it for the watcher)
|
|
260
|
+
if watch != WatcherBackend.LOGURU:
|
|
261
|
+
logger.disable("pipelime")
|
|
262
|
+
|
|
259
263
|
exit_stack.callback(logger.enable, "pipelime")
|
|
260
264
|
exit_stack.callback(PipelimeCommand._track_callback.stop_callbacks)
|
|
261
265
|
|
|
@@ -456,7 +460,8 @@ class WatchCommand(PipelimeCommand, title="watch"):
|
|
|
456
460
|
from pipelime.utils.context_managers import CatchSignals
|
|
457
461
|
|
|
458
462
|
receiver = ProgressReceiverFactory.get_receiver(
|
|
459
|
-
self.token,
|
|
463
|
+
self.token,
|
|
464
|
+
**({"port": self.port} if self.port else {}), # type: ignore
|
|
460
465
|
)
|
|
461
466
|
if isinstance(self.watcher, WatcherBackend):
|
|
462
467
|
callback = ListenerCallbackFactory.get_callback(
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import ast
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
from typing import ClassVar
|
|
5
|
+
|
|
6
|
+
from loguru import logger
|
|
7
|
+
|
|
8
|
+
from pipelime.piper.progress.listener.base import ListenerCallback
|
|
9
|
+
from pipelime.piper.progress.model import ProgressUpdate
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class LoguruListenerCallback(ListenerCallback):
|
|
13
|
+
"""Listener callback that sends progress updates to loguru.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
show_token: Whether to include the token in the logged data.
|
|
17
|
+
log_extras: Extra fields to bind to the logger. Can also be set via
|
|
18
|
+
environment variables with the prefix PIPELIME_PROGRESS_LOG_EXTRA_
|
|
19
|
+
(e.g., PIPELIME_PROGRESS_LOG_EXTRA_key=value). Environment variables
|
|
20
|
+
take precedence over this argument.
|
|
21
|
+
level: Logging level to use. Can also be set via the environment variable
|
|
22
|
+
PIPELIME_PROGRESS_LOG_LEVEL. Defaults to "DEBUG".
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
LOG_LEVEL_ENV_VAR: ClassVar[str] = "PIPELIME_PROGRESS_LOG_LEVEL"
|
|
26
|
+
LOG_EXTRA_ENV_VAR_PREFIX: ClassVar[str] = "PIPELIME_PROGRESS_LOG_EXTRA_"
|
|
27
|
+
|
|
28
|
+
@classmethod
|
|
29
|
+
def update_data(cls, data: dict, prog: ProgressUpdate, show_token: bool) -> None:
|
|
30
|
+
"""Update the data dictionary with the progress update"""
|
|
31
|
+
root = data.setdefault(prog.op_info.token, dict()) if show_token else data
|
|
32
|
+
|
|
33
|
+
chunk_data = root.setdefault(prog.op_info.node, dict()).setdefault(
|
|
34
|
+
str(prog.op_info.chunk), dict()
|
|
35
|
+
)
|
|
36
|
+
chunk_data["message"] = prog.op_info.message
|
|
37
|
+
chunk_data["total"] = prog.op_info.total
|
|
38
|
+
chunk_data["progress"] = prog.progress
|
|
39
|
+
chunk_data["finished"] = prog.finished
|
|
40
|
+
|
|
41
|
+
def __init__(
|
|
42
|
+
self,
|
|
43
|
+
show_token: bool = False,
|
|
44
|
+
log_extras: dict | None = None,
|
|
45
|
+
level: str = "DEBUG",
|
|
46
|
+
) -> None:
|
|
47
|
+
super().__init__(show_token)
|
|
48
|
+
|
|
49
|
+
self._data: dict = dict()
|
|
50
|
+
|
|
51
|
+
# collect log extras from environment variables
|
|
52
|
+
env_extras = {}
|
|
53
|
+
for key, value in os.environ.items():
|
|
54
|
+
if key.startswith(self.LOG_EXTRA_ENV_VAR_PREFIX):
|
|
55
|
+
extra_key = key[len(self.LOG_EXTRA_ENV_VAR_PREFIX) :].lower()
|
|
56
|
+
try:
|
|
57
|
+
env_extras[extra_key] = ast.literal_eval(value)
|
|
58
|
+
except (ValueError, SyntaxError):
|
|
59
|
+
env_extras[extra_key] = value
|
|
60
|
+
|
|
61
|
+
# merge env extras with provided extras (env vars take precedence)
|
|
62
|
+
log_extras = log_extras or {}
|
|
63
|
+
self._log_extras = {**log_extras, **env_extras}
|
|
64
|
+
|
|
65
|
+
# determine log level (env var takes precedence)
|
|
66
|
+
self._level = os.getenv(self.LOG_LEVEL_ENV_VAR, level).upper()
|
|
67
|
+
|
|
68
|
+
def _log_data(self) -> None:
|
|
69
|
+
if self._data:
|
|
70
|
+
logger.bind(**self._log_extras).log(self._level, json.dumps(self._data))
|
|
71
|
+
|
|
72
|
+
def on_update(self, prog: ProgressUpdate) -> None:
|
|
73
|
+
"""Called when a progress update is received"""
|
|
74
|
+
LoguruListenerCallback.update_data(self._data, prog, self.show_token)
|
|
75
|
+
self._log_data()
|
|
76
|
+
|
|
77
|
+
def on_stop(self) -> None:
|
|
78
|
+
"""Called when the listener stops - ensures final progress is sent"""
|
|
79
|
+
self._log_data()
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
|
+
|
|
2
3
|
from pipelime.piper.progress.listener.base import ListenerCallback, ProgressReceiver
|
|
3
|
-
from pipelime.piper.progress.listener.
|
|
4
|
+
from pipelime.piper.progress.listener.callbacks.file import FileListenerCallback
|
|
5
|
+
from pipelime.piper.progress.listener.callbacks.loguru import LoguruListenerCallback
|
|
4
6
|
from pipelime.piper.progress.listener.callbacks.rich_table import (
|
|
5
7
|
RichTableListenerCallback,
|
|
6
8
|
)
|
|
7
9
|
from pipelime.piper.progress.listener.callbacks.tqdm_bars import (
|
|
8
10
|
TqdmBarsListenerCallback,
|
|
9
11
|
)
|
|
10
|
-
from pipelime.piper.progress.listener.
|
|
12
|
+
from pipelime.piper.progress.listener.receiver.zmq import ZMQProgressReceiver
|
|
11
13
|
|
|
12
14
|
|
|
13
15
|
class ProgressReceiverFactory:
|
|
@@ -35,6 +37,7 @@ class ListenerCallbackFactory:
|
|
|
35
37
|
"RICH_TABLE": RichTableListenerCallback,
|
|
36
38
|
"TQDM_BARS": TqdmBarsListenerCallback,
|
|
37
39
|
"FILE": FileListenerCallback,
|
|
40
|
+
"LOGURU": LoguruListenerCallback,
|
|
38
41
|
}
|
|
39
42
|
|
|
40
43
|
@classmethod
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: pipelime-python
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: Data workflows, cli and dataflow automation.
|
|
5
5
|
Project-URL: Source, https://github.com/eyecan-ai/pipelime-python
|
|
6
6
|
Project-URL: Issues, https://github.com/eyecan-ai/pipelime-python/issues
|
|
@@ -19,9 +19,10 @@ Classifier: Programming Language :: Python :: 3
|
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.10
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.11
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
23
|
Classifier: Topic :: Scientific/Engineering
|
|
23
24
|
Classifier: Topic :: Software Development
|
|
24
|
-
Requires-Python: <3.
|
|
25
|
+
Requires-Python: <3.14,>=3.10
|
|
25
26
|
Requires-Dist: albumentations>=1.0.0
|
|
26
27
|
Requires-Dist: astunparse
|
|
27
28
|
Requires-Dist: deepdiff
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
LICENSE,sha256=Ufc-hKELjY574QxuUAosOjRD6RO0x_Y3jtnNbjRK5pc,1525
|
|
2
|
-
pipelime/__init__.py,sha256=
|
|
2
|
+
pipelime/__init__.py,sha256=bT9rQeSERfVxEwn3AugYS3SczbXoOrEPBPwq57BN5Sw,115
|
|
3
3
|
pipelime/choixe/__init__.py,sha256=sFXmatlOorxsGTrB0q6W8RUA0KNqnC4qiRbDRbRZrBM,52
|
|
4
4
|
pipelime/choixe/xconfig.py,sha256=b3ensxAIXgLNw_mVb6_yNnvkHEEGvuJmIN120ACnQlI,15124
|
|
5
5
|
pipelime/choixe/ast/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -22,7 +22,7 @@ pipelime/cli/main.py,sha256=jvK-IabaiOJBW7GxGV_175AY73V5wrr_gStRWQcD9XU,34629
|
|
|
22
22
|
pipelime/cli/parser.py,sha256=8zUpfr5Ijed6dzjomGnT-uVC5xNjBgGl3_Gld8lTKB0,8623
|
|
23
23
|
pipelime/cli/pretty_print.py,sha256=X3jld46DFC_Lmrl9Sejs5Tb5Mmv0bLfPPVdHhR-7fsU,15277
|
|
24
24
|
pipelime/cli/subcommands.py,sha256=NIjzapuj_NVcljd1AWGlVt-r-HOj8noM3nohITta4dk,1705
|
|
25
|
-
pipelime/cli/utils.py,sha256=
|
|
25
|
+
pipelime/cli/utils.py,sha256=H6dXwYO489_jx6_YmvBT4B6hKPzjZDUL8cOzfLL9lhw,28738
|
|
26
26
|
pipelime/cli/tui/__init__.py,sha256=9bmQNLmJHeZIQMcqbU99b7OgrdbeEJKAZ142TD6_fM0,89
|
|
27
27
|
pipelime/cli/tui/tui.css,sha256=_W_Q0eDVT7hAbmBm3KsjA0GnDGheXaasnyZIYC9ZNjU,452
|
|
28
28
|
pipelime/cli/tui/tui.py,sha256=79iNTPe4TvJwkZVnnf-Iqk3rT_b2lntqZon7N5Yxy48,10163
|
|
@@ -30,7 +30,7 @@ pipelime/cli/tui/utils.py,sha256=JaVAzfbdLVzrst6NzNCN5CVO0_gOREOy2142ysmmxkk,644
|
|
|
30
30
|
pipelime/commands/__init__.py,sha256=pk6Xr0MW7FDwtqJPOyzHhz6-vYksRzMw79HlhzhRDj4,741
|
|
31
31
|
pipelime/commands/general.py,sha256=xPJYj5rnS4-aBY4B5AJt9RMZ4cP7JqyQeaG8EaQGGSs,37237
|
|
32
32
|
pipelime/commands/interfaces.py,sha256=aE42ysEy7YMwhzPMrTLoebeYKf4N1KSWKYWuUx_nY3Q,34348
|
|
33
|
-
pipelime/commands/piper.py,sha256=
|
|
33
|
+
pipelime/commands/piper.py,sha256=HkG2dt9UK1dQTq9HNGQ3rwDnabU-t8lBaqf1ED0kPiM,23946
|
|
34
34
|
pipelime/commands/resume.py,sha256=AGcf8UFttxUD5_Ojq7G41NxsKRD_bjXzkqt6rgXURcg,2581
|
|
35
35
|
pipelime/commands/shell.py,sha256=wrW6WGVP_05t28B3CDHQoRb812_wQr8EHOFPemAnXE0,2502
|
|
36
36
|
pipelime/commands/split_ops.py,sha256=hvYYZ4ReoIn2ngkcL-tVaq5qwy1jHRCx0g0rT64lMR0,13669
|
|
@@ -69,9 +69,10 @@ pipelime/piper/progress/estimator/factory.py,sha256=153f9SxceXibIsDELkhzrHAXDVO9
|
|
|
69
69
|
pipelime/piper/progress/estimator/naive.py,sha256=3NGGCD4IQXEORblfs3XEhERRQ8MVgTcwfl8d57ux3Ds,1382
|
|
70
70
|
pipelime/piper/progress/listener/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
71
71
|
pipelime/piper/progress/listener/base.py,sha256=OPHOOs-A0NvCtJkGLmK-r5w6TrPtZ9hCBtQ9XSO21yM,3089
|
|
72
|
-
pipelime/piper/progress/listener/factory.py,sha256=
|
|
72
|
+
pipelime/piper/progress/listener/factory.py,sha256=M4PWel_rlbwMpw0B9rWhggNbZ76Rfyb62yIq4E4u01k,1423
|
|
73
73
|
pipelime/piper/progress/listener/callbacks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
74
74
|
pipelime/piper/progress/listener/callbacks/file.py,sha256=JWRJYoEtsY9mWLdBf1RoMlhTmsUbWv8kD5hOZCVcrCs,2170
|
|
75
|
+
pipelime/piper/progress/listener/callbacks/loguru.py,sha256=Vb8mjK1A2zXDY9o0Juh2vEHuixnpamN7TseMKsv8CMk,3041
|
|
75
76
|
pipelime/piper/progress/listener/callbacks/rich_table.py,sha256=s10TM1arqMz7NTMp9kZeHe-o9HlvdxlUT5xH3_HmJ7M,3442
|
|
76
77
|
pipelime/piper/progress/listener/callbacks/tqdm_bars.py,sha256=3TqKz6g79jaURplmeQg4SkJhEqVSCxK-CsT6_si82Es,1945
|
|
77
78
|
pipelime/piper/progress/listener/receiver/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -113,8 +114,8 @@ pipelime/utils/context_managers.py,sha256=C3ubzFVBPNG_wu1jqKc0o1Vy1sxsZ-UzFKry2g
|
|
|
113
114
|
pipelime/utils/deprecated.py,sha256=rBlOk3cJPZw3jB7QuIY8U3LPWLuovpj8Mfarn65GrqU,1544
|
|
114
115
|
pipelime/utils/inspection.py,sha256=mpfx-wnoDrocpZ5nlh--XtqEGQEEo9WIYIlF18WXXWg,1369
|
|
115
116
|
pipelime/utils/pydantic_types.py,sha256=OGw1bNdWmIRTFkF-fPBHLzAVqaTtrsaS6-mUZ8zgHSg,24955
|
|
116
|
-
pipelime_python-2.
|
|
117
|
-
pipelime_python-2.
|
|
118
|
-
pipelime_python-2.
|
|
119
|
-
pipelime_python-2.
|
|
120
|
-
pipelime_python-2.
|
|
117
|
+
pipelime_python-2.3.0.dist-info/METADATA,sha256=QVznwKUF2I2NPMRnMYj0JxS0HihUzd7IKitKGAHccJ4,8560
|
|
118
|
+
pipelime_python-2.3.0.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
119
|
+
pipelime_python-2.3.0.dist-info/entry_points.txt,sha256=hY61hWhOC6q8tq5Qj5oOOEjZo9dtOrztO7IXylYsoTo,61
|
|
120
|
+
pipelime_python-2.3.0.dist-info/licenses/LICENSE,sha256=Ufc-hKELjY574QxuUAosOjRD6RO0x_Y3jtnNbjRK5pc,1525
|
|
121
|
+
pipelime_python-2.3.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|