liblaf-cherries 0.1.6__py3-none-any.whl → 0.2.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.
- liblaf/cherries/__init__.pyi +8 -87
- liblaf/cherries/_entrypoint.py +56 -0
- liblaf/cherries/_version.py +2 -2
- liblaf/cherries/config/_asset.py +3 -3
- liblaf/cherries/core/__init__.pyi +14 -6
- liblaf/cherries/core/_impl.py +58 -0
- liblaf/cherries/core/_plugin.py +96 -0
- liblaf/cherries/core/_run.py +42 -0
- liblaf/cherries/core/_spec.py +53 -159
- liblaf/cherries/core/typed.py +2 -0
- liblaf/cherries/meta/_git.py +3 -3
- liblaf/cherries/meta/_name.py +3 -3
- liblaf/cherries/{pathutils → paths}/_path.py +9 -7
- liblaf/cherries/plugins/__init__.pyi +3 -0
- liblaf/cherries/plugins/logging.py +25 -0
- liblaf/cherries/profiles/__init__.pyi +13 -0
- liblaf/cherries/profiles/_abc.py +10 -0
- liblaf/cherries/profiles/_default.py +12 -0
- liblaf/cherries/profiles/_factory.py +21 -0
- liblaf/cherries/profiles/_playground.py +13 -0
- {liblaf_cherries-0.1.6.dist-info → liblaf_cherries-0.2.0.dist-info}/METADATA +5 -3
- liblaf_cherries-0.2.0.dist-info/RECORD +43 -0
- liblaf/cherries/_run.py +0 -51
- liblaf/cherries/core/_exp.py +0 -119
- liblaf/cherries/integration/__init__.pyi +0 -72
- liblaf/cherries/integration/_abc.py +0 -144
- liblaf/cherries/integration/_exp.py +0 -109
- liblaf/cherries/integration/comet.py +0 -142
- liblaf/cherries/integration/dvc.py +0 -51
- liblaf/cherries/integration/git.py +0 -44
- liblaf/cherries/integration/logging.py +0 -45
- liblaf/cherries/presets/__init__.pyi +0 -5
- liblaf/cherries/presets/_default.py +0 -46
- liblaf/cherries/presets/_playground.py +0 -11
- liblaf/cherries/presets/typed.py +0 -5
- liblaf_cherries-0.1.6.dist-info/RECORD +0 -44
- /liblaf/cherries/{integration → paths}/__init__.py +0 -0
- /liblaf/cherries/{pathutils → paths}/__init__.pyi +0 -0
- /liblaf/cherries/{pathutils → paths}/_convert.py +0 -0
- /liblaf/cherries/{pathutils → paths}/_special.py +0 -0
- /liblaf/cherries/{pathutils → plugins}/__init__.py +0 -0
- /liblaf/cherries/{presets → profiles}/__init__.py +0 -0
- {liblaf_cherries-0.1.6.dist-info → liblaf_cherries-0.2.0.dist-info}/WHEEL +0 -0
- {liblaf_cherries-0.1.6.dist-info → liblaf_cherries-0.2.0.dist-info}/licenses/LICENSE +0 -0
liblaf/cherries/meta/_name.py
CHANGED
@@ -3,7 +3,7 @@ from pathlib import Path
|
|
3
3
|
import git.exc
|
4
4
|
|
5
5
|
from liblaf import grapes
|
6
|
-
from liblaf.cherries import
|
6
|
+
from liblaf.cherries import paths
|
7
7
|
|
8
8
|
from ._git import git_info
|
9
9
|
|
@@ -18,8 +18,8 @@ def project_name() -> str:
|
|
18
18
|
|
19
19
|
|
20
20
|
def exp_name() -> str:
|
21
|
-
exp_dir: Path =
|
22
|
-
exp_name: str =
|
21
|
+
exp_dir: Path = paths.entrypoint(absolute=False)
|
22
|
+
exp_name: str = paths.as_posix(exp_dir)
|
23
23
|
exp_name = exp_name.removeprefix("exp")
|
24
24
|
exp_name = exp_name.removeprefix("/")
|
25
25
|
return exp_name
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import sys
|
2
|
+
from collections.abc import Container
|
2
3
|
from pathlib import Path
|
3
4
|
|
4
5
|
import git
|
@@ -27,7 +28,7 @@ def git_root_safe() -> Path:
|
|
27
28
|
try:
|
28
29
|
return git_root()
|
29
30
|
except git.exc.InvalidGitRepositoryError:
|
30
|
-
logger.warning("Not in a git repository, using current directory")
|
31
|
+
logger.warning("Not in a git repository, using current directory", once=True)
|
31
32
|
return _entrypoint_absolute().parent
|
32
33
|
|
33
34
|
|
@@ -50,15 +51,16 @@ def _entrypoint_relative() -> Path:
|
|
50
51
|
return path.relative_to(git_root_safe())
|
51
52
|
|
52
53
|
|
54
|
+
EXP_DIR_NAMES: Container[str] = {"exp", "experiment", "experiments", "exps", "src"}
|
55
|
+
|
56
|
+
|
53
57
|
@utils.cache
|
54
58
|
def _exp_dir_absolute() -> Path:
|
55
59
|
entrypoint: Path = _entrypoint_absolute()
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
return path
|
61
|
-
return git_root_safe()
|
60
|
+
parent: Path = entrypoint.parent
|
61
|
+
if parent.name in EXP_DIR_NAMES:
|
62
|
+
return parent.parent
|
63
|
+
return parent
|
62
64
|
|
63
65
|
|
64
66
|
@utils.cache
|
@@ -0,0 +1,25 @@
|
|
1
|
+
from typing import override
|
2
|
+
|
3
|
+
from liblaf import grapes
|
4
|
+
from liblaf.cherries import core
|
5
|
+
|
6
|
+
|
7
|
+
class Logging(core.Run):
|
8
|
+
@override
|
9
|
+
@core.impl
|
10
|
+
def start(self, *args, **kwargs) -> None:
|
11
|
+
profile = grapes.logging.profiles.ProfileCherries(
|
12
|
+
handlers=[
|
13
|
+
grapes.logging.rich_handler(),
|
14
|
+
grapes.logging.file_handler(sink=self.plugin_root.exp_dir / "run.log"),
|
15
|
+
]
|
16
|
+
)
|
17
|
+
grapes.logging.init(profile=profile)
|
18
|
+
|
19
|
+
@override
|
20
|
+
@core.impl
|
21
|
+
def end(self, *args, **kwargs) -> None:
|
22
|
+
if (self.plugin_root.exp_dir / "run.log").exists():
|
23
|
+
self.plugin_root.log_asset(self.plugin_root.exp_dir / "run.log")
|
24
|
+
if (self.plugin_root.exp_dir / "run.log.jsonl").exists():
|
25
|
+
self.plugin_root.log_asset(self.plugin_root.exp_dir / "run.log.jsonl")
|
@@ -0,0 +1,13 @@
|
|
1
|
+
from ._abc import Profile
|
2
|
+
from ._default import ProfileDefault
|
3
|
+
from ._factory import ProfileLike, ProfileName, factory
|
4
|
+
from ._playground import ProfilePlayground
|
5
|
+
|
6
|
+
__all__ = [
|
7
|
+
"Profile",
|
8
|
+
"ProfileDefault",
|
9
|
+
"ProfileLike",
|
10
|
+
"ProfileName",
|
11
|
+
"ProfilePlayground",
|
12
|
+
"factory",
|
13
|
+
]
|
@@ -0,0 +1,12 @@
|
|
1
|
+
from typing import override
|
2
|
+
|
3
|
+
from liblaf.cherries import core
|
4
|
+
|
5
|
+
from ._playground import ProfilePlayground
|
6
|
+
|
7
|
+
|
8
|
+
class ProfileDefault(ProfilePlayground):
|
9
|
+
@override # impl Profile
|
10
|
+
def init(self) -> core.Run:
|
11
|
+
run: core.Run = super().init()
|
12
|
+
return run
|
@@ -0,0 +1,21 @@
|
|
1
|
+
from typing import Literal
|
2
|
+
|
3
|
+
from ._abc import Profile
|
4
|
+
|
5
|
+
# ensure profiles are registered
|
6
|
+
from ._default import ProfileDefault
|
7
|
+
from ._playground import ProfilePlayground # noqa: F401
|
8
|
+
|
9
|
+
# for code-completion
|
10
|
+
type ProfileName = Literal["default", "playground"] | str # noqa: PYI051
|
11
|
+
type ProfileLike = ProfileName | Profile | type[Profile]
|
12
|
+
|
13
|
+
|
14
|
+
def factory(profile: ProfileLike | None = None) -> Profile:
|
15
|
+
if profile is None:
|
16
|
+
return ProfileDefault()
|
17
|
+
if isinstance(profile, str):
|
18
|
+
return Profile[profile]()
|
19
|
+
if isinstance(profile, Profile):
|
20
|
+
return profile
|
21
|
+
return profile()
|
@@ -0,0 +1,13 @@
|
|
1
|
+
from typing import override
|
2
|
+
|
3
|
+
from liblaf.cherries import core, plugins
|
4
|
+
|
5
|
+
from ._abc import Profile
|
6
|
+
|
7
|
+
|
8
|
+
class ProfilePlayground(Profile):
|
9
|
+
@override # impl Profile
|
10
|
+
def init(self) -> core.Run:
|
11
|
+
run: core.Run = core.active_run
|
12
|
+
run.register(plugins.Logging())
|
13
|
+
return run
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: liblaf-cherries
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.2.0
|
4
4
|
Summary: Add your description here
|
5
5
|
Project-URL: Changelog, https://github.com/liblaf/cherries/blob/main/CHANGELOG.md
|
6
6
|
Project-URL: Documentation, https://liblaf.github.io/cherries/
|
@@ -31,17 +31,19 @@ Classifier: Topic :: System :: Logging
|
|
31
31
|
Classifier: Topic :: Utilities
|
32
32
|
Classifier: Typing :: Typed
|
33
33
|
Requires-Python: >=3.12
|
34
|
+
Requires-Dist: attrs<26,>=25.0.0
|
34
35
|
Requires-Dist: comet-ml<4,>=3.0.0
|
35
36
|
Requires-Dist: dvc[webdav]<4,>=3.0.0
|
36
37
|
Requires-Dist: environs<15,>=14.0.0
|
37
38
|
Requires-Dist: gitpython<4,>=3.0.0
|
38
|
-
Requires-Dist: lazy-loader<0.5,>=0.4
|
39
|
-
Requires-Dist: liblaf-grapes<0.
|
39
|
+
Requires-Dist: lazy-loader<0.5,>=0.4
|
40
|
+
Requires-Dist: liblaf-grapes<0.7,>=0.6.0
|
40
41
|
Requires-Dist: loguru<0.8,>=0.7.0
|
41
42
|
Requires-Dist: networkx<4,>=3.0.0
|
42
43
|
Requires-Dist: pydantic-settings<3,>=2.0.0
|
43
44
|
Requires-Dist: pydantic<3,>=2.0.0
|
44
45
|
Requires-Dist: rich<15,>=14.0.0
|
46
|
+
Requires-Dist: wrapt<2,>=1.0.0
|
45
47
|
Description-Content-Type: text/markdown
|
46
48
|
|
47
49
|
<div align="center" markdown><a name="readme-top"></a>
|
@@ -0,0 +1,43 @@
|
|
1
|
+
liblaf/cherries/__init__.py,sha256=OHb6Xou2v6u42swTgjRfzej4CIlRg4OmgOIQXUiRjKA,97
|
2
|
+
liblaf/cherries/__init__.pyi,sha256=urWKt4Q2hPNdZK-eLO1fkqqbIJ0dtiHTb6QYWgDojkA,823
|
3
|
+
liblaf/cherries/_entrypoint.py,sha256=bBjzM770-9lybNq0qtSYdiIPsWIVoHttgkxj02myyAU,1581
|
4
|
+
liblaf/cherries/_version.py,sha256=iB5DfB5V6YB5Wo4JmvS-txT42QtmGaWcWp3udRT7zCI,511
|
5
|
+
liblaf/cherries/_version.pyi,sha256=Pnv4Bxw13LHeuVkPLPsTtnp4N4jOGcAfFJw05uMMgBY,108
|
6
|
+
liblaf/cherries/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
|
+
liblaf/cherries/typed.py,sha256=mim8QVtwczTSHyw5mhEdfFcXis9o32n0CZyu8BrEorE,50
|
8
|
+
liblaf/cherries/config/__init__.py,sha256=OHb6Xou2v6u42swTgjRfzej4CIlRg4OmgOIQXUiRjKA,97
|
9
|
+
liblaf/cherries/config/__init__.pyi,sha256=1CMEQlPneeRXCG51KDUj6Zmqs0xzUF3gilqeuHPlsVc,359
|
10
|
+
liblaf/cherries/config/_asset.py,sha256=OZQ521GIOWNWMdcF_iV3t5ZG5XhdlaQ6_diuqP_DPx0,2472
|
11
|
+
liblaf/cherries/config/_config.py,sha256=WPwwk-3O96FyHGb2W8__LDfHpXBHLQM44aOcrMPjDL4,171
|
12
|
+
liblaf/cherries/core/__init__.py,sha256=OHb6Xou2v6u42swTgjRfzej4CIlRg4OmgOIQXUiRjKA,97
|
13
|
+
liblaf/cherries/core/__init__.pyi,sha256=3hAxoGwuAYfJs5UzYGiyZSwA4nYNarGziceK7jh-CLs,414
|
14
|
+
liblaf/cherries/core/_impl.py,sha256=1sRAIdWNB5eLJ45cZOdLn0VZ06mqkxI6r5GXSMXoUWo,1374
|
15
|
+
liblaf/cherries/core/_plugin.py,sha256=mZxki48dC64CxsOj5dZiKlSPZG9zioun_pP0y3AHtZo,3138
|
16
|
+
liblaf/cherries/core/_run.py,sha256=O8B2aOZwxdnwBfAv24nA7FkFn7KgLF9EjFkeQs6hcrQ,1020
|
17
|
+
liblaf/cherries/core/_spec.py,sha256=b6sTw5C08dnAjw_YRcGyd32XbSTvGMekkzE_qPvZI9g,1789
|
18
|
+
liblaf/cherries/core/typed.py,sha256=razpiUtLAGFD9J4H5RbIEHKEXWzxFHFjtOBBRllhea4,42
|
19
|
+
liblaf/cherries/meta/__init__.py,sha256=OHb6Xou2v6u42swTgjRfzej4CIlRg4OmgOIQXUiRjKA,97
|
20
|
+
liblaf/cherries/meta/__init__.pyi,sha256=kQFneP3IiV9rBIzpep_uX0z-5IRPrXkPmyNRt19j8fg,282
|
21
|
+
liblaf/cherries/meta/_git.py,sha256=HhxqwKY52KahvAYU0R3BTRNT7lMJIjJLpnuSYfm02W4,1219
|
22
|
+
liblaf/cherries/meta/_name.py,sha256=JdV47Ji4qHUILe8GEfIMC_MgkwKx2ottXqwotJ5XwS0,548
|
23
|
+
liblaf/cherries/paths/__init__.py,sha256=OHb6Xou2v6u42swTgjRfzej4CIlRg4OmgOIQXUiRjKA,97
|
24
|
+
liblaf/cherries/paths/__init__.pyi,sha256=mr3Dk8ragpNGXmXJriMt21vc7YmqUD6X587exFe9tCI,413
|
25
|
+
liblaf/cherries/paths/_convert.py,sha256=IrXN_9s-rfH7EKk0_ilr1giGmfN8FlvB_edm2kI-k3I,807
|
26
|
+
liblaf/cherries/paths/_path.py,sha256=Wz3C4ZgERzP659I_eC1N9lMokyyvbIedCMs3PpYrYus,1606
|
27
|
+
liblaf/cherries/paths/_special.py,sha256=b5D3PtW__u0Zpiv69OYoV7TTYc6Dgs4Bu-P8jwrROV4,1415
|
28
|
+
liblaf/cherries/plugins/__init__.py,sha256=OHb6Xou2v6u42swTgjRfzej4CIlRg4OmgOIQXUiRjKA,97
|
29
|
+
liblaf/cherries/plugins/__init__.pyi,sha256=PUOon4osKSfGEQCj6NG2wUgwCOh4G8LcHfOad_RFs6o,52
|
30
|
+
liblaf/cherries/plugins/logging.py,sha256=_Dzzc-jBWIvWWhfq_i-dq2IsX1Vnan0cDNy7Sar_Uvc,836
|
31
|
+
liblaf/cherries/profiles/__init__.py,sha256=OHb6Xou2v6u42swTgjRfzej4CIlRg4OmgOIQXUiRjKA,97
|
32
|
+
liblaf/cherries/profiles/__init__.pyi,sha256=qXxy2LOG9hE0LKCnECdJSv2VoHhOTMVDE3sUKIuZKmw,292
|
33
|
+
liblaf/cherries/profiles/_abc.py,sha256=1tpRrocBZNHonWaj3a264GnL5UoGS_HqU06aNZpruqY,193
|
34
|
+
liblaf/cherries/profiles/_default.py,sha256=7V0BkyB80iVOI7bray4rWHGYlMqN3oEzAg3eOJ2XRWI,269
|
35
|
+
liblaf/cherries/profiles/_factory.py,sha256=FhYfHBmWe0uPOhRmCCg8zilUggHIPIllrPDx4Gkc8C8,602
|
36
|
+
liblaf/cherries/profiles/_playground.py,sha256=QS_YjYu5ewloF3_U4dZFmqCHx3WVHyIKcqsVe1WbYrc,295
|
37
|
+
liblaf/cherries/utils/__init__.py,sha256=OHb6Xou2v6u42swTgjRfzej4CIlRg4OmgOIQXUiRjKA,97
|
38
|
+
liblaf/cherries/utils/__init__.pyi,sha256=F5aTcXpWVmUoctPbLfmQXKyuXYRspAIjaIzfL1_3Lrw,51
|
39
|
+
liblaf/cherries/utils/_functools.py,sha256=0Puwvj1Wq4kp3S--hI-CXwUBZ56AtfkqIzFHllQtuug,181
|
40
|
+
liblaf_cherries-0.2.0.dist-info/METADATA,sha256=yH-oOPeBTRybMUFCvinx6g3lTpNn000NxbkP4bDjxI4,6256
|
41
|
+
liblaf_cherries-0.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
42
|
+
liblaf_cherries-0.2.0.dist-info/licenses/LICENSE,sha256=Ph4NzyU3lGVDeYv-mf8aRmImH8v9rVL9F362FV4G6Ow,1063
|
43
|
+
liblaf_cherries-0.2.0.dist-info/RECORD,,
|
liblaf/cherries/_run.py
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
from collections.abc import Callable
|
2
|
-
from typing import get_type_hints
|
3
|
-
|
4
|
-
import pydantic
|
5
|
-
|
6
|
-
from liblaf.cherries import config, integration, presets
|
7
|
-
from liblaf.cherries import pathutils as _path
|
8
|
-
|
9
|
-
|
10
|
-
def run[C: pydantic.BaseModel, T](
|
11
|
-
main: Callable[[], T] | Callable[[C], T],
|
12
|
-
*,
|
13
|
-
play: bool = False,
|
14
|
-
preset: presets.Preset = presets.default,
|
15
|
-
) -> T:
|
16
|
-
exp: integration.Experiment = start(preset=preset, play=play)
|
17
|
-
type_hints: dict[str, type[C]] = get_type_hints(main)
|
18
|
-
del type_hints["return"]
|
19
|
-
args: list[C] = []
|
20
|
-
if len(type_hints) == 1:
|
21
|
-
cls: type[C] = next(iter(type_hints.values()))
|
22
|
-
cfg: C = cls()
|
23
|
-
args.append(cfg)
|
24
|
-
for path in config.get_inputs(cfg):
|
25
|
-
exp.log_input(path)
|
26
|
-
try:
|
27
|
-
result: T = main(*args)
|
28
|
-
finally:
|
29
|
-
if len(type_hints) == 1:
|
30
|
-
cfg: C = args[0]
|
31
|
-
for path in config.get_outputs(cfg):
|
32
|
-
exp.log_output(path)
|
33
|
-
exp.end()
|
34
|
-
return result
|
35
|
-
|
36
|
-
|
37
|
-
def start(
|
38
|
-
preset: presets.Preset = presets.default, *, play: bool = False
|
39
|
-
) -> integration.Experiment:
|
40
|
-
if play:
|
41
|
-
preset = presets.playground
|
42
|
-
exp: integration.Experiment = preset(integration.exp)
|
43
|
-
exp.start()
|
44
|
-
exp.log_other("cherries.entrypoint", _path.entrypoint(absolute=False))
|
45
|
-
exp.log_other("cherries.exp-dir", _path.exp_dir(absolute=False))
|
46
|
-
exp.log_other("cherries.start-time", exp.start_time)
|
47
|
-
return exp
|
48
|
-
|
49
|
-
|
50
|
-
def end() -> None:
|
51
|
-
integration.exp.end()
|
liblaf/cherries/core/_exp.py
DELETED
@@ -1,119 +0,0 @@
|
|
1
|
-
import datetime
|
2
|
-
import functools
|
3
|
-
from pathlib import Path
|
4
|
-
from typing import Any
|
5
|
-
|
6
|
-
from liblaf.cherries import pathutils as _path
|
7
|
-
from liblaf.cherries.typed import PathLike
|
8
|
-
|
9
|
-
from ._spec import Plugin, spec
|
10
|
-
|
11
|
-
|
12
|
-
class Experiment(Plugin):
|
13
|
-
@functools.cached_property
|
14
|
-
def exp_dir(self) -> Path:
|
15
|
-
return _path.exp_dir(absolute=True)
|
16
|
-
|
17
|
-
@property
|
18
|
-
def exp_id(self) -> str:
|
19
|
-
return self.get_exp_id()
|
20
|
-
|
21
|
-
@property
|
22
|
-
def exp_name(self) -> str:
|
23
|
-
return self.get_exp_name()
|
24
|
-
|
25
|
-
@exp_name.setter
|
26
|
-
def exp_name(self, value: str) -> None:
|
27
|
-
self.set_exp_name(value)
|
28
|
-
|
29
|
-
@property
|
30
|
-
def exp_url(self) -> str:
|
31
|
-
return self.get_exp_url()
|
32
|
-
|
33
|
-
@property
|
34
|
-
def project_id(self) -> str:
|
35
|
-
return self.get_project_id()
|
36
|
-
|
37
|
-
@property
|
38
|
-
def project_name(self) -> str:
|
39
|
-
return self.get_project_name()
|
40
|
-
|
41
|
-
@functools.cached_property
|
42
|
-
def start_time(self) -> datetime.datetime:
|
43
|
-
return datetime.datetime.now().astimezone()
|
44
|
-
|
45
|
-
def log_input(self, path: PathLike, /, **kwargs) -> None:
|
46
|
-
self.log_asset(path, prefix="inputs/", **kwargs)
|
47
|
-
|
48
|
-
def log_output(self, path: PathLike, /, **kwargs) -> None:
|
49
|
-
self.log_asset(path, prefix="outputs/", **kwargs)
|
50
|
-
|
51
|
-
@spec
|
52
|
-
def add_tag(self, tag: str, /) -> None: ...
|
53
|
-
|
54
|
-
@spec
|
55
|
-
def add_tags(self, tags: list[str], /) -> None: ...
|
56
|
-
|
57
|
-
@spec
|
58
|
-
def end(self) -> None: ...
|
59
|
-
|
60
|
-
@spec(firstresult=True)
|
61
|
-
def get_exp_id(self) -> str: ...
|
62
|
-
|
63
|
-
@spec(firstresult=True)
|
64
|
-
def get_exp_name(self) -> str: ...
|
65
|
-
|
66
|
-
@spec(firstresult=True)
|
67
|
-
def get_exp_url(self) -> str: ...
|
68
|
-
|
69
|
-
@spec(firstresult=True)
|
70
|
-
def get_project_id(self) -> str: ...
|
71
|
-
|
72
|
-
@spec(firstresult=True)
|
73
|
-
def get_project_name(self) -> str: ...
|
74
|
-
|
75
|
-
@spec(firstresult=True)
|
76
|
-
def get_project_url(self) -> str: ...
|
77
|
-
|
78
|
-
@spec
|
79
|
-
def log_asset(self, path: PathLike, /, prefix: str | None = None) -> None: ...
|
80
|
-
|
81
|
-
@spec
|
82
|
-
def log_code(self, path: str, /) -> None: ...
|
83
|
-
|
84
|
-
@spec
|
85
|
-
def log_metric(
|
86
|
-
self,
|
87
|
-
key: str,
|
88
|
-
value: float,
|
89
|
-
/,
|
90
|
-
step: int | None = None,
|
91
|
-
epoch: int | None = None,
|
92
|
-
) -> None: ...
|
93
|
-
|
94
|
-
@spec
|
95
|
-
def log_metrics(
|
96
|
-
self,
|
97
|
-
metrics: dict[str, float],
|
98
|
-
/,
|
99
|
-
step: int | None = None,
|
100
|
-
epoch: int | None = None,
|
101
|
-
) -> None: ...
|
102
|
-
|
103
|
-
@spec
|
104
|
-
def log_other(self, key: str, value: Any, /) -> None: ...
|
105
|
-
|
106
|
-
@spec
|
107
|
-
def log_others(self, others: dict[str, Any], /) -> None: ...
|
108
|
-
|
109
|
-
@spec
|
110
|
-
def log_param(self, key: str, value: Any, /) -> None: ...
|
111
|
-
|
112
|
-
@spec
|
113
|
-
def log_params(self, params: dict[str, Any], /) -> None: ...
|
114
|
-
|
115
|
-
@spec
|
116
|
-
def set_exp_name(self, name: str, /) -> None: ...
|
117
|
-
|
118
|
-
@spec
|
119
|
-
def start(self) -> None: ...
|
@@ -1,72 +0,0 @@
|
|
1
|
-
from . import comet, dvc, git, logging
|
2
|
-
from ._abc import (
|
3
|
-
AddTag,
|
4
|
-
AddTags,
|
5
|
-
End,
|
6
|
-
LogAsset,
|
7
|
-
LogCode,
|
8
|
-
LogMetric,
|
9
|
-
LogMetrics,
|
10
|
-
LogOther,
|
11
|
-
LogOthers,
|
12
|
-
LogParam,
|
13
|
-
LogParams,
|
14
|
-
Plugin,
|
15
|
-
Start,
|
16
|
-
)
|
17
|
-
from ._exp import (
|
18
|
-
Experiment,
|
19
|
-
add_tag,
|
20
|
-
add_tags,
|
21
|
-
current_exp,
|
22
|
-
end,
|
23
|
-
exp,
|
24
|
-
log_asset,
|
25
|
-
log_code,
|
26
|
-
log_input,
|
27
|
-
log_metric,
|
28
|
-
log_metrics,
|
29
|
-
log_other,
|
30
|
-
log_others,
|
31
|
-
log_output,
|
32
|
-
log_param,
|
33
|
-
log_params,
|
34
|
-
start,
|
35
|
-
)
|
36
|
-
|
37
|
-
__all__ = [
|
38
|
-
"AddTag",
|
39
|
-
"AddTags",
|
40
|
-
"End",
|
41
|
-
"Experiment",
|
42
|
-
"LogAsset",
|
43
|
-
"LogCode",
|
44
|
-
"LogMetric",
|
45
|
-
"LogMetrics",
|
46
|
-
"LogOther",
|
47
|
-
"LogOthers",
|
48
|
-
"LogParam",
|
49
|
-
"LogParams",
|
50
|
-
"Plugin",
|
51
|
-
"Start",
|
52
|
-
"add_tag",
|
53
|
-
"add_tags",
|
54
|
-
"comet",
|
55
|
-
"current_exp",
|
56
|
-
"dvc",
|
57
|
-
"end",
|
58
|
-
"exp",
|
59
|
-
"git",
|
60
|
-
"log_asset",
|
61
|
-
"log_code",
|
62
|
-
"log_input",
|
63
|
-
"log_metric",
|
64
|
-
"log_metrics",
|
65
|
-
"log_other",
|
66
|
-
"log_others",
|
67
|
-
"log_output",
|
68
|
-
"log_param",
|
69
|
-
"log_params",
|
70
|
-
"logging",
|
71
|
-
"start",
|
72
|
-
]
|
@@ -1,144 +0,0 @@
|
|
1
|
-
import bisect
|
2
|
-
import functools
|
3
|
-
import operator
|
4
|
-
from collections.abc import Iterable, Mapping
|
5
|
-
from typing import Any
|
6
|
-
|
7
|
-
import attrs
|
8
|
-
from loguru import logger
|
9
|
-
|
10
|
-
from liblaf.cherries.typed import PathLike
|
11
|
-
|
12
|
-
|
13
|
-
@attrs.define
|
14
|
-
@functools.total_ordering
|
15
|
-
class Plugin[**P, T]:
|
16
|
-
priority: int = attrs.field(default=0, kw_only=True)
|
17
|
-
_children: list["Plugin"] = attrs.field(
|
18
|
-
factory=list, eq=False, order=False, alias="children"
|
19
|
-
)
|
20
|
-
|
21
|
-
def __attrs_post_init__(self) -> None:
|
22
|
-
self._children.sort(key=operator.attrgetter("priority"))
|
23
|
-
|
24
|
-
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> T:
|
25
|
-
ret: T | None = None
|
26
|
-
for child in self._children:
|
27
|
-
try:
|
28
|
-
ret = child(*args, **kwargs)
|
29
|
-
except BaseException as err:
|
30
|
-
if isinstance(err, (KeyboardInterrupt, SystemExit)):
|
31
|
-
raise
|
32
|
-
logger.exception(child)
|
33
|
-
return ret # pyright: ignore[reportReturnType]
|
34
|
-
|
35
|
-
def __lt__(self, other: "Plugin") -> bool:
|
36
|
-
if not isinstance(other, Plugin):
|
37
|
-
return NotImplemented
|
38
|
-
return self.priority < other.priority
|
39
|
-
|
40
|
-
def __eq__(self, other: "Plugin") -> bool: # pyright: ignore[reportIncompatibleMethodOverride]
|
41
|
-
if not isinstance(other, Plugin):
|
42
|
-
return NotImplemented
|
43
|
-
return self.priority == other.priority
|
44
|
-
|
45
|
-
@property
|
46
|
-
def children(self) -> list["Plugin"]:
|
47
|
-
return self._children
|
48
|
-
|
49
|
-
def add(self, *children: "Plugin") -> None:
|
50
|
-
for c in children:
|
51
|
-
bisect.insort(self._children, c, key=operator.attrgetter("priority"))
|
52
|
-
|
53
|
-
def extend(self, children: Iterable["Plugin"]) -> None:
|
54
|
-
self.add(*children)
|
55
|
-
|
56
|
-
def remove(self, child: "Plugin") -> None:
|
57
|
-
self._children.remove(child)
|
58
|
-
|
59
|
-
|
60
|
-
@attrs.define
|
61
|
-
class AddTag(Plugin):
|
62
|
-
def __call__(self, tag: str, /, **kwargs) -> None:
|
63
|
-
super().__call__(tag, **kwargs)
|
64
|
-
|
65
|
-
|
66
|
-
@attrs.define
|
67
|
-
class AddTags(Plugin):
|
68
|
-
def __call__(self, tags: Iterable[str], /, **kwargs) -> None:
|
69
|
-
super().__call__(tags, **kwargs)
|
70
|
-
|
71
|
-
|
72
|
-
@attrs.define
|
73
|
-
class End(Plugin):
|
74
|
-
def __call__(self, **kwargs) -> None:
|
75
|
-
super().__call__(**kwargs)
|
76
|
-
|
77
|
-
|
78
|
-
@attrs.define
|
79
|
-
class LogAsset(Plugin):
|
80
|
-
def __call__(self, path: PathLike, /, prefix: str | None = None, **kwargs) -> None:
|
81
|
-
super().__call__(path, prefix=prefix, **kwargs)
|
82
|
-
|
83
|
-
|
84
|
-
@attrs.define
|
85
|
-
class LogCode(Plugin):
|
86
|
-
def __call__(self, path: PathLike, /, **kwargs) -> None:
|
87
|
-
super().__call__(path, **kwargs)
|
88
|
-
|
89
|
-
|
90
|
-
@attrs.define
|
91
|
-
class LogMetric(Plugin):
|
92
|
-
def __call__(
|
93
|
-
self,
|
94
|
-
key: str,
|
95
|
-
value: float,
|
96
|
-
/,
|
97
|
-
step: int | None = None,
|
98
|
-
epoch: int | None = None,
|
99
|
-
**kwargs,
|
100
|
-
) -> None:
|
101
|
-
super().__call__(key, value, step=step, epoch=epoch, **kwargs)
|
102
|
-
|
103
|
-
|
104
|
-
@attrs.define
|
105
|
-
class LogMetrics(Plugin):
|
106
|
-
def __call__(
|
107
|
-
self,
|
108
|
-
metrics: Mapping[str, Any],
|
109
|
-
/,
|
110
|
-
step: int | None = None,
|
111
|
-
epoch: int | None = None,
|
112
|
-
**kwargs,
|
113
|
-
) -> None:
|
114
|
-
super().__call__(metrics, step=step, epoch=epoch, **kwargs)
|
115
|
-
|
116
|
-
|
117
|
-
@attrs.define
|
118
|
-
class LogOther(Plugin):
|
119
|
-
def __call__(self, key: str, value: Any, /, **kwargs) -> None:
|
120
|
-
super().__call__(key, value, **kwargs)
|
121
|
-
|
122
|
-
|
123
|
-
@attrs.define
|
124
|
-
class LogOthers(Plugin):
|
125
|
-
def __call__(self, others: Mapping[str, Any], /, **kwargs) -> None:
|
126
|
-
super().__call__(others, **kwargs)
|
127
|
-
|
128
|
-
|
129
|
-
@attrs.define
|
130
|
-
class LogParam(Plugin):
|
131
|
-
def __call__(self, name: str, value: Any, /, **kwargs) -> None:
|
132
|
-
super().__call__(name, value, **kwargs)
|
133
|
-
|
134
|
-
|
135
|
-
@attrs.define
|
136
|
-
class LogParams(Plugin):
|
137
|
-
def __call__(self, params: Mapping[str, Any], /, **kwargs) -> None:
|
138
|
-
super().__call__(params, **kwargs)
|
139
|
-
|
140
|
-
|
141
|
-
@attrs.define
|
142
|
-
class Start(Plugin):
|
143
|
-
def __call__(self, **kwargs) -> None:
|
144
|
-
super().__call__(**kwargs)
|