liblaf-cherries 0.2.1__py3-none-any.whl → 0.2.2__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.
@@ -1,7 +1,24 @@
1
- from . import config, core, meta, paths
1
+ from . import config, core, meta, paths, plugins
2
2
  from ._entrypoint import end, run, start
3
3
  from .config import BaseConfig, input, output # noqa: A004
4
- from .core import Plugin, Run, active_run, log_asset, log_metrics
4
+ from .core import (
5
+ Plugin,
6
+ Run,
7
+ active_run,
8
+ log_asset,
9
+ log_asset_data,
10
+ log_asset_folder,
11
+ log_input,
12
+ log_input_folder,
13
+ log_metric,
14
+ log_metrics,
15
+ log_other,
16
+ log_others,
17
+ log_output,
18
+ log_output_folder,
19
+ log_parameter,
20
+ log_parameters,
21
+ )
5
22
  from .paths import (
6
23
  as_os_path,
7
24
  as_path,
@@ -37,13 +54,25 @@ __all__ = [
37
54
  "input",
38
55
  "inputs",
39
56
  "log_asset",
57
+ "log_asset_data",
58
+ "log_asset_folder",
59
+ "log_input",
60
+ "log_input_folder",
61
+ "log_metric",
40
62
  "log_metrics",
63
+ "log_other",
64
+ "log_others",
65
+ "log_output",
66
+ "log_output_folder",
67
+ "log_parameter",
68
+ "log_parameters",
41
69
  "meta",
42
70
  "output",
43
71
  "outputs",
44
72
  "params",
45
73
  "path",
46
74
  "paths",
75
+ "plugins",
47
76
  "run",
48
77
  "src",
49
78
  "start",
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.2.1'
21
- __version_tuple__ = version_tuple = (0, 2, 1)
20
+ __version__ = version = '0.2.2'
21
+ __version_tuple__ = version_tuple = (0, 2, 2)
@@ -1,6 +1,24 @@
1
1
  from ._impl import ImplInfo, get_impl_info, impl
2
2
  from ._plugin import Plugin
3
- from ._run import Run, active_run, log_asset, log_metrics
3
+ from ._run import (
4
+ Run,
5
+ active_run,
6
+ end,
7
+ log_asset,
8
+ log_asset_data,
9
+ log_asset_folder,
10
+ log_input,
11
+ log_input_folder,
12
+ log_metric,
13
+ log_metrics,
14
+ log_other,
15
+ log_others,
16
+ log_output,
17
+ log_output_folder,
18
+ log_parameter,
19
+ log_parameters,
20
+ start,
21
+ )
4
22
  from ._spec import SpecInfo, spec
5
23
  from .typed import MethodName, PluginId
6
24
 
@@ -12,9 +30,22 @@ __all__ = [
12
30
  "Run",
13
31
  "SpecInfo",
14
32
  "active_run",
33
+ "end",
15
34
  "get_impl_info",
16
35
  "impl",
17
36
  "log_asset",
37
+ "log_asset_data",
38
+ "log_asset_folder",
39
+ "log_input",
40
+ "log_input_folder",
41
+ "log_metric",
18
42
  "log_metrics",
43
+ "log_other",
44
+ "log_others",
45
+ "log_output",
46
+ "log_output_folder",
47
+ "log_parameter",
48
+ "log_parameters",
19
49
  "spec",
50
+ "start",
20
51
  ]
@@ -3,6 +3,7 @@ from collections.abc import Callable, Iterable
3
3
  from typing import Any, overload
4
4
 
5
5
  import attrs
6
+ import wrapt
6
7
 
7
8
  from liblaf import grapes
8
9
 
@@ -41,18 +42,19 @@ def impl(
41
42
  ) -> Any:
42
43
  if func is None:
43
44
  return functools.partial(impl, priority=priority, after=after, before=before)
44
- info = ImplInfo(after=after, before=before, priority=priority)
45
45
 
46
- @grapes.decorator(attrs={"_self_impl": info})
46
+ @wrapt.decorator
47
47
  def wrapper(
48
48
  wrapped: Callable, _instance: Any, args: tuple, kwargs: dict[str, Any]
49
49
  ) -> Any:
50
50
  return wrapped(*args, **kwargs)
51
51
 
52
- return wrapper(func)
52
+ proxy: Any = wrapper(func) # pyright: ignore[reportCallIssue]
53
+ proxy._self_impl = ImplInfo(after=after, before=before, priority=priority) # noqa: SLF001
54
+ return proxy
53
55
 
54
56
 
55
57
  def get_impl_info(func: Callable | None) -> ImplInfo | None:
56
58
  if func is None:
57
59
  return None
58
- return getattr(func, "_self_impl", None)
60
+ return grapes.unbind_getattr(func, "_self_impl", None)
@@ -1,4 +1,3 @@
1
- import inspect
2
1
  from collections.abc import Mapping, MutableMapping, Sequence
3
2
  from typing import Any, Self
4
3
 
@@ -6,7 +5,7 @@ import attrs
6
5
  import networkx as nx
7
6
 
8
7
  from ._impl import ImplInfo, get_impl_info
9
- from ._spec import SpecInfo
8
+ from ._spec import SpecInfo, collect_specs
10
9
  from .typed import MethodName
11
10
 
12
11
 
@@ -33,15 +32,6 @@ class Plugin:
33
32
  return self
34
33
  return self._plugin_parent.plugin_root
35
34
 
36
- @property
37
- def specs(self) -> dict[str, SpecInfo]:
38
- return {
39
- name: method._self_spec # noqa: SLF001
40
- for name, method in inspect.getmembers(
41
- type(self), lambda m: getattr(m, "_self_spec", None) is not None
42
- )
43
- }
44
-
45
35
  def delegate(
46
36
  self,
47
37
  method: MethodName,
@@ -65,7 +55,8 @@ class Plugin:
65
55
  self.plugins[plugin.plugin_id] = plugin
66
56
 
67
57
  def _prepare(self) -> None:
68
- for method in self.specs:
58
+ specs: dict[str, SpecInfo] = collect_specs(self)
59
+ for method in specs:
69
60
  self._sort_plugins_cache[method] = self._sort_plugins(
70
61
  method, refresh_cache=True
71
62
  )
@@ -1,4 +1,6 @@
1
+ from collections.abc import Mapping
1
2
  from pathlib import Path
3
+ from typing import Any
2
4
 
3
5
  import attrs
4
6
 
@@ -22,14 +24,65 @@ class Run(Plugin):
22
24
  def exp_dir(self) -> Path:
23
25
  return paths.exp_dir(absolute=True)
24
26
 
27
+ @property
28
+ def url(self) -> str:
29
+ return self.get_url()
30
+
25
31
  @spec
26
32
  def end(self, *args, **kwargs) -> None: ...
27
-
33
+ @spec(first_result=True)
34
+ def get_url(self) -> str: ...
28
35
  @spec
29
36
  def log_asset(self, *args, **kwargs) -> None: ...
30
-
31
37
  @spec
32
- def log_metrics(self, *args, **kwargs) -> None: ...
38
+ def log_asset_data(self, *args, **kwargs) -> None: ...
39
+ @spec
40
+ def log_asset_folder(self, *args, **kwargs) -> None: ...
41
+ @spec
42
+ def log_input(self, *args, **kwargs) -> None: ...
43
+ @spec
44
+ def log_input_folder(self, *args, **kwargs) -> None: ...
45
+ @spec
46
+ def log_metric(
47
+ self,
48
+ name: str,
49
+ value: Any,
50
+ /,
51
+ step: int | None = None,
52
+ epoch: int | None = None,
53
+ **kwargs,
54
+ ) -> None: ...
55
+ @spec
56
+ def log_metrics(
57
+ self,
58
+ dic: Mapping[str, Any],
59
+ /,
60
+ prefix: str | None = None,
61
+ step: int | None = None,
62
+ epoch: int | None = None,
63
+ **kwargs,
64
+ ) -> None: ...
65
+ @spec
66
+ def log_other(self, key: Any, value: Any, /, **kwargs) -> None: ...
67
+ @spec
68
+ def log_others(self, dictionary: Mapping[Any, Any], /, **kwargs) -> None: ...
69
+ @spec
70
+ def log_output(self, *args, **kwargs) -> None: ...
71
+ @spec
72
+ def log_output_folder(self, *args, **kwargs) -> None: ...
73
+ @spec
74
+ def log_parameter(
75
+ self, name: Any, value: Any, /, step: int | None = None, **kwargs
76
+ ) -> None: ...
77
+ @spec
78
+ def log_parameters(
79
+ self,
80
+ parameters: Mapping[Any, Any],
81
+ /,
82
+ prefix: str | None = None,
83
+ step: int | None = None,
84
+ **kwargs,
85
+ ) -> None: ...
33
86
 
34
87
  @spec(delegate=False)
35
88
  def start(self, *args, **kwargs) -> None:
@@ -38,5 +91,18 @@ class Run(Plugin):
38
91
 
39
92
 
40
93
  active_run: Run = Run()
94
+ end = active_run.end
41
95
  log_asset = active_run.log_asset
96
+ log_asset_data = active_run.log_asset_data
97
+ log_asset_folder = active_run.log_asset_folder
98
+ log_input = active_run.log_input
99
+ log_input_folder = active_run.log_input_folder
100
+ log_metric = active_run.log_metric
42
101
  log_metrics = active_run.log_metrics
102
+ log_other = active_run.log_other
103
+ log_others = active_run.log_others
104
+ log_output = active_run.log_output
105
+ log_output_folder = active_run.log_output_folder
106
+ log_parameter = active_run.log_parameter
107
+ log_parameters = active_run.log_parameters
108
+ start = active_run.start
@@ -4,6 +4,7 @@ from collections.abc import Callable, Mapping, Sequence
4
4
  from typing import Any, Protocol, overload
5
5
 
6
6
  import attrs
7
+ import wrapt
7
8
 
8
9
  from liblaf import grapes
9
10
 
@@ -47,7 +48,7 @@ def spec(
47
48
 
48
49
  info = SpecInfo(delegate=delegate, first_result=first_result)
49
50
 
50
- @grapes.decorator(attrs={"_self_spec": info})
51
+ @wrapt.decorator
51
52
  def wrapper(
52
53
  wrapped: Callable, instance: Plugin, args: tuple, kwargs: dict[str, Any]
53
54
  ) -> Any:
@@ -57,15 +58,17 @@ def spec(
57
58
  )
58
59
  return wrapped(*args, **kwargs)
59
60
 
60
- return wrapper(func)
61
+ proxy: Any = wrapper(func) # pyright: ignore[reportCallIssue]
62
+ proxy._self_spec = SpecInfo(delegate=delegate, first_result=first_result) # noqa: SLF001
63
+ return proxy
61
64
 
62
65
 
63
66
  def collect_specs(cls: type[Plugin] | Plugin) -> dict[str, SpecInfo]:
64
67
  if isinstance(cls, type):
65
68
  cls = type(cls)
66
69
  return {
67
- name: method._self_spec # noqa: SLF001
70
+ name: grapes.unbind_getattr(method, "_self_spec")
68
71
  for name, method in inspect.getmembers(
69
- cls, lambda m: getattr(m, "_self_spec", None) is not None
72
+ cls, lambda m: grapes.unbind_getattr(m, "_self_spec", None) is not None
70
73
  )
71
74
  }
@@ -1,3 +1,4 @@
1
+ from .comet import Comet
1
2
  from .logging import Logging
2
3
 
3
- __all__ = ["Logging"]
4
+ __all__ = ["Comet", "Logging"]
@@ -0,0 +1,54 @@
1
+ from typing import override
2
+
3
+ import comet_ml
4
+
5
+ from liblaf.cherries import core
6
+
7
+
8
+ class Comet(core.Run):
9
+ exp: comet_ml.CometExperiment
10
+
11
+ @override
12
+ @core.impl(after=("Logging",))
13
+ def end(self, *args, **kwargs) -> None:
14
+ return self.exp.end()
15
+
16
+ @override
17
+ @core.impl
18
+ def get_url(self) -> str:
19
+ return self.exp.url # pyright: ignore[reportReturnType]
20
+
21
+ @override
22
+ @core.impl
23
+ def log_metric(self, *args, **kwargs) -> None:
24
+ return self.exp.log_metric(*args, **kwargs)
25
+
26
+ @override
27
+ @core.impl
28
+ def log_metrics(self, *args, **kwargs) -> None:
29
+ return self.exp.log_metrics(*args, **kwargs)
30
+
31
+ @override
32
+ @core.impl
33
+ def log_other(self, *args, **kwargs) -> None:
34
+ return self.exp.log_other(*args, **kwargs)
35
+
36
+ @override
37
+ @core.impl
38
+ def log_others(self, *args, **kwargs) -> None:
39
+ return self.exp.log_others(*args, **kwargs)
40
+
41
+ @override
42
+ @core.impl
43
+ def log_parameter(self, *args, **kwargs) -> None:
44
+ return self.exp.log_parameter(*args, **kwargs)
45
+
46
+ @override
47
+ @core.impl
48
+ def log_parameters(self, *args, **kwargs) -> None:
49
+ return self.exp.log_parameters(*args, **kwargs)
50
+
51
+ @override
52
+ @core.impl(after=("Logging",))
53
+ def start(self, *args, **kwargs) -> None:
54
+ self.exp = comet_ml.start()
@@ -10,7 +10,8 @@ class Logging(core.Run):
10
10
  def start(self, *args, **kwargs) -> None:
11
11
  profile = grapes.logging.profiles.ProfileCherries(
12
12
  handlers=[
13
- grapes.logging.rich_handler(),
13
+ # Comet and many other services do not support links
14
+ grapes.logging.rich_handler(enable_link=False),
14
15
  grapes.logging.file_handler(sink=self.plugin_root.exp_dir / "run.log"),
15
16
  ]
16
17
  )
@@ -1,6 +1,6 @@
1
1
  from typing import override
2
2
 
3
- from liblaf.cherries import core
3
+ from liblaf.cherries import core, plugins
4
4
 
5
5
  from ._playground import ProfilePlayground
6
6
 
@@ -9,4 +9,5 @@ class ProfileDefault(ProfilePlayground):
9
9
  @override # impl Profile
10
10
  def init(self) -> core.Run:
11
11
  run: core.Run = super().init()
12
+ run.register(plugins.Comet())
12
13
  return run
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: liblaf-cherries
3
- Version: 0.2.1
3
+ Version: 0.2.2
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/
@@ -37,7 +37,7 @@ Requires-Dist: dvc[webdav]<4,>=3.0.0
37
37
  Requires-Dist: environs<15,>=14.0.0
38
38
  Requires-Dist: gitpython<4,>=3.0.0
39
39
  Requires-Dist: lazy-loader<0.5,>=0.4
40
- Requires-Dist: liblaf-grapes<1.1,>=1
40
+ Requires-Dist: liblaf-grapes<2,>=1.0.0
41
41
  Requires-Dist: loguru<0.8,>=0.7.0
42
42
  Requires-Dist: networkx<4,>=3.0.0
43
43
  Requires-Dist: pydantic-settings<3,>=2.0.0
@@ -1,7 +1,7 @@
1
1
  liblaf/cherries/__init__.py,sha256=OHb6Xou2v6u42swTgjRfzej4CIlRg4OmgOIQXUiRjKA,97
2
- liblaf/cherries/__init__.pyi,sha256=urWKt4Q2hPNdZK-eLO1fkqqbIJ0dtiHTb6QYWgDojkA,823
2
+ liblaf/cherries/__init__.pyi,sha256=_4VWvFPs2Kpr-u1tO_YU8SmFdhZPNUmOvtJQo9qXn4Q,1302
3
3
  liblaf/cherries/_entrypoint.py,sha256=bBjzM770-9lybNq0qtSYdiIPsWIVoHttgkxj02myyAU,1581
4
- liblaf/cherries/_version.py,sha256=UoNvMtd4wCG76RwoSpNCUtaFyTwakGcZolfjXzNVSMY,511
4
+ liblaf/cherries/_version.py,sha256=OjGGK5TcHVG44Y62aAqeJH4CskkZoY9ydbHOtCDew50,511
5
5
  liblaf/cherries/_version.pyi,sha256=Pnv4Bxw13LHeuVkPLPsTtnp4N4jOGcAfFJw05uMMgBY,108
6
6
  liblaf/cherries/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  liblaf/cherries/typed.py,sha256=mim8QVtwczTSHyw5mhEdfFcXis9o32n0CZyu8BrEorE,50
@@ -10,11 +10,11 @@ liblaf/cherries/config/__init__.pyi,sha256=1CMEQlPneeRXCG51KDUj6Zmqs0xzUF3gilqeu
10
10
  liblaf/cherries/config/_asset.py,sha256=OZQ521GIOWNWMdcF_iV3t5ZG5XhdlaQ6_diuqP_DPx0,2472
11
11
  liblaf/cherries/config/_config.py,sha256=WPwwk-3O96FyHGb2W8__LDfHpXBHLQM44aOcrMPjDL4,171
12
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
13
+ liblaf/cherries/core/__init__.pyi,sha256=9jbA822Znhm9AHXR_zhcM74e8pikNAdkkSpNUOjKQjI,909
14
+ liblaf/cherries/core/_impl.py,sha256=LCd4f5oX5bEMa4uX37r0yiPntqZM1Lwqrd7vKL1oc7w,1459
15
+ liblaf/cherries/core/_plugin.py,sha256=dBK5re9yAB8kfp4Uc5fu5aVLms_lMi2bB4jDJEayvfs,2905
16
+ liblaf/cherries/core/_run.py,sha256=3VMT4fVIoWU5FYss5SzKgWAr9vcYWwbrQCiMh7aeG44,2972
17
+ liblaf/cherries/core/_spec.py,sha256=F73wxygkc_3v0hOKwfFSGaLRHEDhhENWLQZakruuRq8,1950
18
18
  liblaf/cherries/core/typed.py,sha256=razpiUtLAGFD9J4H5RbIEHKEXWzxFHFjtOBBRllhea4,42
19
19
  liblaf/cherries/meta/__init__.py,sha256=OHb6Xou2v6u42swTgjRfzej4CIlRg4OmgOIQXUiRjKA,97
20
20
  liblaf/cherries/meta/__init__.pyi,sha256=kQFneP3IiV9rBIzpep_uX0z-5IRPrXkPmyNRt19j8fg,282
@@ -26,18 +26,19 @@ liblaf/cherries/paths/_convert.py,sha256=IrXN_9s-rfH7EKk0_ilr1giGmfN8FlvB_edm2kI
26
26
  liblaf/cherries/paths/_path.py,sha256=Wz3C4ZgERzP659I_eC1N9lMokyyvbIedCMs3PpYrYus,1606
27
27
  liblaf/cherries/paths/_special.py,sha256=b5D3PtW__u0Zpiv69OYoV7TTYc6Dgs4Bu-P8jwrROV4,1415
28
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
29
+ liblaf/cherries/plugins/__init__.pyi,sha256=80ZJM2XNFDGjclyCzmlTia0nzDPuOADV8jirU8ZGc_g,86
30
+ liblaf/cherries/plugins/comet.py,sha256=R2rUS2n6ynSqKwADRS7ZKij09DZtUJ2Lm8LbsCB9P3U,1331
31
+ liblaf/cherries/plugins/logging.py,sha256=pZut8_TnCZscjkyRpTcw3PWhL1Vv1FJ60f-XcpSNPbI,922
31
32
  liblaf/cherries/profiles/__init__.py,sha256=OHb6Xou2v6u42swTgjRfzej4CIlRg4OmgOIQXUiRjKA,97
32
33
  liblaf/cherries/profiles/__init__.pyi,sha256=qXxy2LOG9hE0LKCnECdJSv2VoHhOTMVDE3sUKIuZKmw,292
33
34
  liblaf/cherries/profiles/_abc.py,sha256=1tpRrocBZNHonWaj3a264GnL5UoGS_HqU06aNZpruqY,193
34
- liblaf/cherries/profiles/_default.py,sha256=7V0BkyB80iVOI7bray4rWHGYlMqN3oEzAg3eOJ2XRWI,269
35
+ liblaf/cherries/profiles/_default.py,sha256=8fsEAN6s9ZDxngX1PMb9JISIfC6pilEWYgynuXn5TxY,316
35
36
  liblaf/cherries/profiles/_factory.py,sha256=FhYfHBmWe0uPOhRmCCg8zilUggHIPIllrPDx4Gkc8C8,602
36
37
  liblaf/cherries/profiles/_playground.py,sha256=QS_YjYu5ewloF3_U4dZFmqCHx3WVHyIKcqsVe1WbYrc,295
37
38
  liblaf/cherries/utils/__init__.py,sha256=OHb6Xou2v6u42swTgjRfzej4CIlRg4OmgOIQXUiRjKA,97
38
39
  liblaf/cherries/utils/__init__.pyi,sha256=F5aTcXpWVmUoctPbLfmQXKyuXYRspAIjaIzfL1_3Lrw,51
39
40
  liblaf/cherries/utils/_functools.py,sha256=0Puwvj1Wq4kp3S--hI-CXwUBZ56AtfkqIzFHllQtuug,181
40
- liblaf_cherries-0.2.1.dist-info/METADATA,sha256=YZ8wRa6oe2uwraxGLT_N-8kZQBh46V4_lBIMpeTfgjU,6252
41
- liblaf_cherries-0.2.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
42
- liblaf_cherries-0.2.1.dist-info/licenses/LICENSE,sha256=Ph4NzyU3lGVDeYv-mf8aRmImH8v9rVL9F362FV4G6Ow,1063
43
- liblaf_cherries-0.2.1.dist-info/RECORD,,
41
+ liblaf_cherries-0.2.2.dist-info/METADATA,sha256=KMA-Ya-Ao2z-V5kSEXUKB4_iFkIJtfJtOS83KF97ZsE,6254
42
+ liblaf_cherries-0.2.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
43
+ liblaf_cherries-0.2.2.dist-info/licenses/LICENSE,sha256=Ph4NzyU3lGVDeYv-mf8aRmImH8v9rVL9F362FV4G6Ow,1063
44
+ liblaf_cherries-0.2.2.dist-info/RECORD,,