liblaf-cherries 0.0.14__py3-none-any.whl → 0.1.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 +71 -44
- liblaf/cherries/_run.py +38 -26
- liblaf/cherries/_version.py +2 -2
- liblaf/cherries/config/__init__.pyi +23 -0
- liblaf/cherries/config/_asset.py +72 -0
- liblaf/cherries/config/_config.py +6 -0
- liblaf/cherries/integration/__init__.pyi +66 -0
- liblaf/cherries/integration/_abc.py +144 -0
- liblaf/cherries/integration/_exp.py +97 -0
- liblaf/cherries/integration/comet.py +142 -0
- liblaf/cherries/integration/dvc.py +51 -0
- liblaf/cherries/integration/git.py +44 -0
- liblaf/cherries/integration/logging.py +45 -0
- liblaf/cherries/meta/__init__.py +3 -0
- liblaf/cherries/{info → meta}/__init__.pyi +2 -2
- liblaf/cherries/meta/_name.py +25 -0
- liblaf/cherries/pathutils/__init__.pyi +2 -2
- liblaf/cherries/pathutils/_convert.py +0 -4
- liblaf/cherries/pathutils/_path.py +6 -6
- liblaf/cherries/pathutils/_special.py +2 -2
- liblaf/cherries/presets/__init__.pyi +3 -1
- liblaf/cherries/presets/_default.py +37 -23
- liblaf/cherries/presets/_playground.py +11 -0
- liblaf/cherries/presets/typed.py +5 -0
- {liblaf_cherries-0.0.14.dist-info → liblaf_cherries-0.1.0.dist-info}/METADATA +5 -5
- liblaf_cherries-0.1.0.dist-info/RECORD +40 -0
- liblaf/cherries/_config.py +0 -22
- liblaf/cherries/info/_name.py +0 -30
- liblaf/cherries/plugin/__init__.pyi +0 -77
- liblaf/cherries/plugin/_abc.py +0 -131
- liblaf/cherries/plugin/_dvc.py +0 -63
- liblaf/cherries/plugin/_git.py +0 -46
- liblaf/cherries/plugin/_logging.py +0 -31
- liblaf/cherries/plugin/_mlflow.py +0 -88
- liblaf/cherries/plugin/_run.py +0 -105
- liblaf_cherries-0.0.14.dist-info/RECORD +0 -35
- /liblaf/cherries/{info → config}/__init__.py +0 -0
- /liblaf/cherries/{plugin → integration}/__init__.py +0 -0
- /liblaf/cherries/{info → meta}/_git.py +0 -0
- {liblaf_cherries-0.0.14.dist-info → liblaf_cherries-0.1.0.dist-info}/WHEEL +0 -0
- {liblaf_cherries-0.0.14.dist-info → liblaf_cherries-0.1.0.dist-info}/licenses/LICENSE +0 -0
liblaf/cherries/__init__.pyi
CHANGED
@@ -1,89 +1,116 @@
|
|
1
|
-
from . import
|
2
|
-
from ._config import BaseConfig
|
1
|
+
from . import config, integration, meta, pathutils, presets, utils
|
3
2
|
from ._run import end, run, start
|
3
|
+
from .config import (
|
4
|
+
AssetKind,
|
5
|
+
BaseConfig,
|
6
|
+
MetaAsset,
|
7
|
+
PathProvider,
|
8
|
+
get_assets,
|
9
|
+
get_inputs,
|
10
|
+
get_outputs,
|
11
|
+
input, # noqa: A004
|
12
|
+
output,
|
13
|
+
)
|
14
|
+
from .integration import (
|
15
|
+
AddTag,
|
16
|
+
AddTags,
|
17
|
+
End,
|
18
|
+
Experiment,
|
19
|
+
LogAsset,
|
20
|
+
LogCode,
|
21
|
+
LogMetric,
|
22
|
+
LogMetrics,
|
23
|
+
LogOther,
|
24
|
+
LogOthers,
|
25
|
+
LogParam,
|
26
|
+
LogParams,
|
27
|
+
Plugin,
|
28
|
+
Start,
|
29
|
+
add_tag,
|
30
|
+
add_tags,
|
31
|
+
log_asset,
|
32
|
+
log_code,
|
33
|
+
log_metric,
|
34
|
+
log_metrics,
|
35
|
+
log_other,
|
36
|
+
log_others,
|
37
|
+
log_param,
|
38
|
+
log_params,
|
39
|
+
)
|
4
40
|
from .pathutils import (
|
5
41
|
as_os_path,
|
6
42
|
as_path,
|
7
43
|
as_posix,
|
8
|
-
config,
|
9
44
|
data,
|
10
45
|
entrypoint,
|
46
|
+
exp_dir,
|
11
47
|
git_root,
|
12
48
|
git_root_safe,
|
13
49
|
inputs,
|
14
50
|
outputs,
|
15
51
|
params,
|
16
52
|
path,
|
17
|
-
run_dir,
|
18
53
|
src,
|
19
54
|
)
|
20
|
-
from .plugin import (
|
21
|
-
End,
|
22
|
-
LogArtifact,
|
23
|
-
LogArtifacts,
|
24
|
-
LoggingEnd,
|
25
|
-
LoggingStart,
|
26
|
-
LogMetric,
|
27
|
-
LogParam,
|
28
|
-
Plugin,
|
29
|
-
Run,
|
30
|
-
RunStatus,
|
31
|
-
Start,
|
32
|
-
log_artifact,
|
33
|
-
log_artifacts,
|
34
|
-
log_input,
|
35
|
-
log_inputs,
|
36
|
-
log_metric,
|
37
|
-
log_output,
|
38
|
-
log_outputs,
|
39
|
-
log_param,
|
40
|
-
log_src,
|
41
|
-
set_tag,
|
42
|
-
)
|
43
55
|
|
44
56
|
__all__ = [
|
57
|
+
"AddTag",
|
58
|
+
"AddTags",
|
59
|
+
"AssetKind",
|
45
60
|
"BaseConfig",
|
46
61
|
"End",
|
47
|
-
"
|
48
|
-
"
|
62
|
+
"Experiment",
|
63
|
+
"LogAsset",
|
64
|
+
"LogCode",
|
49
65
|
"LogMetric",
|
66
|
+
"LogMetrics",
|
67
|
+
"LogOther",
|
68
|
+
"LogOthers",
|
50
69
|
"LogParam",
|
51
|
-
"
|
52
|
-
"
|
70
|
+
"LogParams",
|
71
|
+
"MetaAsset",
|
72
|
+
"PathProvider",
|
53
73
|
"Plugin",
|
54
|
-
"Run",
|
55
|
-
"RunStatus",
|
56
74
|
"Start",
|
75
|
+
"add_tag",
|
76
|
+
"add_tags",
|
57
77
|
"as_os_path",
|
58
78
|
"as_path",
|
59
79
|
"as_posix",
|
60
80
|
"config",
|
61
81
|
"data",
|
62
82
|
"end",
|
83
|
+
"end",
|
84
|
+
"end",
|
63
85
|
"entrypoint",
|
86
|
+
"exp_dir",
|
87
|
+
"get_assets",
|
88
|
+
"get_inputs",
|
89
|
+
"get_outputs",
|
64
90
|
"git_root",
|
65
91
|
"git_root_safe",
|
66
|
-
"
|
92
|
+
"input",
|
67
93
|
"inputs",
|
68
|
-
"
|
69
|
-
"
|
70
|
-
"
|
71
|
-
"log_inputs",
|
94
|
+
"integration",
|
95
|
+
"log_asset",
|
96
|
+
"log_code",
|
72
97
|
"log_metric",
|
73
|
-
"
|
74
|
-
"
|
98
|
+
"log_metrics",
|
99
|
+
"log_other",
|
100
|
+
"log_others",
|
75
101
|
"log_param",
|
76
|
-
"
|
102
|
+
"log_params",
|
103
|
+
"meta",
|
104
|
+
"output",
|
77
105
|
"outputs",
|
78
106
|
"params",
|
79
107
|
"path",
|
80
108
|
"pathutils",
|
81
|
-
"plugin",
|
82
109
|
"presets",
|
83
110
|
"run",
|
84
|
-
"
|
85
|
-
"set_tag",
|
111
|
+
"run",
|
86
112
|
"src",
|
87
113
|
"start",
|
114
|
+
"start",
|
88
115
|
"utils",
|
89
116
|
]
|
liblaf/cherries/_run.py
CHANGED
@@ -3,37 +3,49 @@ from typing import get_type_hints
|
|
3
3
|
|
4
4
|
import pydantic
|
5
5
|
|
6
|
+
from liblaf.cherries import config, integration, presets
|
6
7
|
from liblaf.cherries import pathutils as _path
|
7
|
-
from liblaf.cherries import plugin, presets
|
8
8
|
|
9
9
|
|
10
|
-
def run[C: pydantic.BaseModel, T](
|
11
|
-
|
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)
|
12
17
|
type_hints: dict[str, type[C]] = get_type_hints(main)
|
13
|
-
|
14
|
-
|
15
|
-
|
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)
|
16
26
|
try:
|
17
|
-
|
18
|
-
|
19
|
-
if
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
36
48
|
|
37
49
|
|
38
50
|
def end() -> None:
|
39
|
-
|
51
|
+
integration.exp.end()
|
liblaf/cherries/_version.py
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
from ._asset import (
|
2
|
+
AssetKind,
|
3
|
+
MetaAsset,
|
4
|
+
PathProvider,
|
5
|
+
get_assets,
|
6
|
+
get_inputs,
|
7
|
+
get_outputs,
|
8
|
+
input, # noqa: A004
|
9
|
+
output,
|
10
|
+
)
|
11
|
+
from ._config import BaseConfig
|
12
|
+
|
13
|
+
__all__ = [
|
14
|
+
"AssetKind",
|
15
|
+
"BaseConfig",
|
16
|
+
"MetaAsset",
|
17
|
+
"PathProvider",
|
18
|
+
"get_assets",
|
19
|
+
"get_inputs",
|
20
|
+
"get_outputs",
|
21
|
+
"input",
|
22
|
+
"output",
|
23
|
+
]
|
@@ -0,0 +1,72 @@
|
|
1
|
+
import enum
|
2
|
+
from collections.abc import Callable, Iterable
|
3
|
+
from pathlib import Path
|
4
|
+
from typing import Any
|
5
|
+
|
6
|
+
import pydantic
|
7
|
+
|
8
|
+
from liblaf import grapes
|
9
|
+
from liblaf.cherries import pathutils as _path
|
10
|
+
from liblaf.cherries.typed import PathLike
|
11
|
+
|
12
|
+
|
13
|
+
class AssetKind(enum.StrEnum):
|
14
|
+
INPUT = enum.auto()
|
15
|
+
OUTPUT = enum.auto()
|
16
|
+
|
17
|
+
|
18
|
+
type PathProvider = (
|
19
|
+
PathLike | Iterable[PathLike] | Callable[[PathLike], PathLike | Iterable[PathLike]]
|
20
|
+
)
|
21
|
+
|
22
|
+
|
23
|
+
class MetaAsset:
|
24
|
+
kind: AssetKind
|
25
|
+
_extra: PathProvider | None = None
|
26
|
+
|
27
|
+
def __init__(self, kind: AssetKind, extra: PathProvider | None = None) -> None:
|
28
|
+
self.kind = kind
|
29
|
+
self._extra = extra
|
30
|
+
|
31
|
+
def get_extra(self, value: Path) -> list[Path]:
|
32
|
+
if self._extra is None:
|
33
|
+
return []
|
34
|
+
if callable(self._extra):
|
35
|
+
extra: Iterable[PathLike] = grapes.as_iterable(self._extra(value))
|
36
|
+
return [Path(p) for p in extra]
|
37
|
+
extra: Iterable[PathLike] = grapes.as_iterable(self._extra)
|
38
|
+
return [Path(p) for p in extra]
|
39
|
+
|
40
|
+
|
41
|
+
def get_assets(cfg: pydantic.BaseModel, kind: AssetKind) -> list[Path]:
|
42
|
+
assets: list[Path] = []
|
43
|
+
for name, info in type(cfg).model_fields.items():
|
44
|
+
value: Any = getattr(cfg, name)
|
45
|
+
if isinstance(value, pydantic.BaseModel):
|
46
|
+
assets.extend(get_assets(value, kind))
|
47
|
+
for meta in info.metadata:
|
48
|
+
if isinstance(meta, MetaAsset) and meta.kind == kind:
|
49
|
+
value: Path = Path(value)
|
50
|
+
assets.append(value)
|
51
|
+
assets.extend(meta.get_extra(value))
|
52
|
+
return assets
|
53
|
+
|
54
|
+
|
55
|
+
def get_inputs(cfg: pydantic.BaseModel) -> list[Path]:
|
56
|
+
return get_assets(cfg, AssetKind.INPUT)
|
57
|
+
|
58
|
+
|
59
|
+
def get_outputs(cfg: pydantic.BaseModel) -> list[Path]:
|
60
|
+
return get_assets(cfg, AssetKind.OUTPUT)
|
61
|
+
|
62
|
+
|
63
|
+
def input(path: PathLike, extra: PathProvider | None = None, **kwargs) -> Path: # noqa: A001
|
64
|
+
field_info: pydantic.fields.FieldInfo = pydantic.Field(_path.data(path), **kwargs) # pyright: ignore[reportAssignmentType]
|
65
|
+
field_info.metadata.append(MetaAsset(kind=AssetKind.INPUT, extra=extra))
|
66
|
+
return field_info # pyright: ignore[reportReturnType]
|
67
|
+
|
68
|
+
|
69
|
+
def output(path: PathLike, extra: PathProvider | None = None, **kwargs) -> Path:
|
70
|
+
field_info: pydantic.fields.FieldInfo = pydantic.Field(_path.data(path), **kwargs) # pyright: ignore[reportAssignmentType]
|
71
|
+
field_info.metadata.append(MetaAsset(kind=AssetKind.OUTPUT, extra=extra))
|
72
|
+
return field_info # pyright: ignore[reportReturnType]
|
@@ -0,0 +1,66 @@
|
|
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
|
+
end,
|
22
|
+
exp,
|
23
|
+
log_asset,
|
24
|
+
log_code,
|
25
|
+
log_metric,
|
26
|
+
log_metrics,
|
27
|
+
log_other,
|
28
|
+
log_others,
|
29
|
+
log_param,
|
30
|
+
log_params,
|
31
|
+
start,
|
32
|
+
)
|
33
|
+
|
34
|
+
__all__ = [
|
35
|
+
"AddTag",
|
36
|
+
"AddTags",
|
37
|
+
"End",
|
38
|
+
"Experiment",
|
39
|
+
"LogAsset",
|
40
|
+
"LogCode",
|
41
|
+
"LogMetric",
|
42
|
+
"LogMetrics",
|
43
|
+
"LogOther",
|
44
|
+
"LogOthers",
|
45
|
+
"LogParam",
|
46
|
+
"LogParams",
|
47
|
+
"Plugin",
|
48
|
+
"Start",
|
49
|
+
"add_tag",
|
50
|
+
"add_tags",
|
51
|
+
"comet",
|
52
|
+
"dvc",
|
53
|
+
"end",
|
54
|
+
"exp",
|
55
|
+
"git",
|
56
|
+
"log_asset",
|
57
|
+
"log_code",
|
58
|
+
"log_metric",
|
59
|
+
"log_metrics",
|
60
|
+
"log_other",
|
61
|
+
"log_others",
|
62
|
+
"log_param",
|
63
|
+
"log_params",
|
64
|
+
"logging",
|
65
|
+
"start",
|
66
|
+
]
|
@@ -0,0 +1,144 @@
|
|
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)
|
@@ -0,0 +1,97 @@
|
|
1
|
+
import datetime
|
2
|
+
import functools
|
3
|
+
from os import PathLike
|
4
|
+
from pathlib import Path
|
5
|
+
|
6
|
+
import attrs
|
7
|
+
import comet_ml as comet
|
8
|
+
|
9
|
+
from liblaf.cherries import pathutils as _path
|
10
|
+
|
11
|
+
from ._abc import (
|
12
|
+
AddTag,
|
13
|
+
AddTags,
|
14
|
+
End,
|
15
|
+
LogAsset,
|
16
|
+
LogCode,
|
17
|
+
LogMetric,
|
18
|
+
LogMetrics,
|
19
|
+
LogOther,
|
20
|
+
LogOthers,
|
21
|
+
LogParam,
|
22
|
+
LogParams,
|
23
|
+
Start,
|
24
|
+
)
|
25
|
+
|
26
|
+
|
27
|
+
@attrs.define
|
28
|
+
class Experiment:
|
29
|
+
add_tag: AddTag = attrs.field(factory=AddTag, init=False)
|
30
|
+
add_tags: AddTags = attrs.field(factory=AddTags, init=False)
|
31
|
+
end: End = attrs.field(factory=End, init=False)
|
32
|
+
log_asset: LogAsset = attrs.field(factory=LogAsset, init=False)
|
33
|
+
log_code: LogCode = attrs.field(factory=LogCode, init=False)
|
34
|
+
log_metric: LogMetric = attrs.field(factory=LogMetric, init=False)
|
35
|
+
log_metrics: LogMetrics = attrs.field(factory=LogMetrics, init=False)
|
36
|
+
log_other: LogOther = attrs.field(factory=LogOther, init=False)
|
37
|
+
log_others: LogOthers = attrs.field(factory=LogOthers, init=False)
|
38
|
+
log_param: LogParam = attrs.field(factory=LogParam, init=False)
|
39
|
+
log_params: LogParams = attrs.field(factory=LogParams, init=False)
|
40
|
+
start: Start = attrs.field(factory=Start, init=False)
|
41
|
+
|
42
|
+
@property
|
43
|
+
def comet(self) -> comet.CometExperiment:
|
44
|
+
return comet.get_running_experiment() # pyright: ignore[reportReturnType]
|
45
|
+
|
46
|
+
@functools.cached_property
|
47
|
+
def exp_dir(self) -> Path:
|
48
|
+
return _path.exp_dir(absolute=True)
|
49
|
+
|
50
|
+
@property
|
51
|
+
def exp_key(self) -> str:
|
52
|
+
return self.comet.get_key()
|
53
|
+
|
54
|
+
@property
|
55
|
+
def exp_name(self) -> str:
|
56
|
+
return self.comet.get_name()
|
57
|
+
|
58
|
+
@exp_name.setter
|
59
|
+
def exp_name(self, value: str) -> None:
|
60
|
+
self.comet.set_name(value)
|
61
|
+
|
62
|
+
@property
|
63
|
+
def exp_url(self) -> str:
|
64
|
+
return self.comet.url # pyright: ignore[reportReturnType]
|
65
|
+
|
66
|
+
@property
|
67
|
+
def project_id(self) -> str:
|
68
|
+
return self.comet.project_id # pyright: ignore[reportReturnType]
|
69
|
+
|
70
|
+
@property
|
71
|
+
def project_name(self) -> str:
|
72
|
+
return self.comet.project_name
|
73
|
+
|
74
|
+
@functools.cached_property
|
75
|
+
def start_time(self) -> datetime.datetime:
|
76
|
+
return datetime.datetime.now().astimezone()
|
77
|
+
|
78
|
+
def log_input(self, path: PathLike, /, **kwargs) -> None:
|
79
|
+
self.log_asset(path, prefix="inputs/", **kwargs)
|
80
|
+
|
81
|
+
def log_output(self, path: PathLike, /, **kwargs) -> None:
|
82
|
+
self.log_asset(path, prefix="outputs/", **kwargs)
|
83
|
+
|
84
|
+
|
85
|
+
exp = Experiment()
|
86
|
+
add_tag: AddTag = exp.add_tag
|
87
|
+
add_tags: AddTags = exp.add_tags
|
88
|
+
end: End = exp.end
|
89
|
+
log_asset: LogAsset = exp.log_asset
|
90
|
+
log_code: LogCode = exp.log_code
|
91
|
+
log_metric: LogMetric = exp.log_metric
|
92
|
+
log_metrics: LogMetrics = exp.log_metrics
|
93
|
+
log_other: LogOther = exp.log_other
|
94
|
+
log_others: LogOthers = exp.log_others
|
95
|
+
log_param: LogParam = exp.log_param
|
96
|
+
log_params: LogParams = exp.log_params
|
97
|
+
start: Start = exp.start
|