liblaf-cherries 0.0.9__py3-none-any.whl → 0.0.10__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.
Files changed (47) hide show
  1. liblaf/cherries/__init__.pyi +74 -23
  2. liblaf/cherries/_run.py +31 -26
  3. liblaf/cherries/_version.py +2 -2
  4. liblaf/cherries/info/__init__.pyi +11 -0
  5. liblaf/cherries/info/_exp_name.py +19 -0
  6. liblaf/cherries/info/_git.py +49 -0
  7. liblaf/cherries/pathutils/__init__.pyi +20 -0
  8. liblaf/cherries/pathutils/_convert.py +40 -0
  9. liblaf/cherries/pathutils/_path.py +68 -0
  10. liblaf/cherries/pathutils/_special.py +50 -0
  11. liblaf/cherries/plugin/__init__.pyi +72 -6
  12. liblaf/cherries/plugin/_abc.py +112 -21
  13. liblaf/cherries/plugin/_dvc.py +47 -0
  14. liblaf/cherries/plugin/_git.py +41 -18
  15. liblaf/cherries/plugin/_logging.py +22 -30
  16. liblaf/cherries/plugin/_mlflow.py +73 -0
  17. liblaf/cherries/plugin/_run.py +104 -0
  18. liblaf/cherries/presets/__init__.pyi +3 -0
  19. liblaf/cherries/presets/_default.py +32 -0
  20. liblaf/cherries/typed.py +3 -0
  21. liblaf/cherries/utils/__init__.pyi +3 -0
  22. liblaf/cherries/utils/_functools.py +6 -0
  23. {liblaf_cherries-0.0.9.dist-info → liblaf_cherries-0.0.10.dist-info}/METADATA +7 -5
  24. liblaf_cherries-0.0.10.dist-info/RECORD +35 -0
  25. liblaf/cherries/_env.py +0 -4
  26. liblaf/cherries/_experiment.py +0 -111
  27. liblaf/cherries/_main.py +0 -38
  28. liblaf/cherries/_start.py +0 -26
  29. liblaf/cherries/git/__init__.pyi +0 -18
  30. liblaf/cherries/git/_commit.py +0 -17
  31. liblaf/cherries/git/_entrypoint.py +0 -12
  32. liblaf/cherries/git/_grapes.py +0 -3
  33. liblaf/cherries/git/github/__init__.pyi +0 -4
  34. liblaf/cherries/git/github/_link.py +0 -25
  35. liblaf/cherries/git/github/_repo.py +0 -23
  36. liblaf/cherries/integration/__init__.pyi +0 -5
  37. liblaf/cherries/integration/_backend.py +0 -53
  38. liblaf/cherries/integration/_factory.py +0 -13
  39. liblaf/cherries/integration/_neptune.py +0 -66
  40. liblaf/cherries/plugin/_default.py +0 -9
  41. liblaf/cherries/plugin/_restic.py +0 -60
  42. liblaf_cherries-0.0.9.dist-info/RECORD +0 -38
  43. /liblaf/cherries/{git → info}/__init__.py +0 -0
  44. /liblaf/cherries/{git/github → pathutils}/__init__.py +0 -0
  45. /liblaf/cherries/{integration → presets}/__init__.py +0 -0
  46. {liblaf_cherries-0.0.9.dist-info → liblaf_cherries-0.0.10.dist-info}/WHEEL +0 -0
  47. {liblaf_cherries-0.0.9.dist-info → liblaf_cherries-0.0.10.dist-info}/licenses/LICENSE +0 -0
@@ -1,17 +0,0 @@
1
- import subprocess as sp
2
-
3
- import git
4
-
5
- DEFAULT_COMMIT_MESSAGE: str = """chore(exp): auto commit"""
6
-
7
-
8
- def commit(message: str = DEFAULT_COMMIT_MESSAGE, *, dry_run: bool = False) -> bool:
9
- repo = git.Repo(search_parent_directories=True)
10
- if not repo.is_dirty(untracked_files=True):
11
- return False
12
- repo.git.add(all=True, dry_run=dry_run)
13
- sp.run(["git", "status"], check=False)
14
- if dry_run:
15
- return False
16
- repo.git.commit(message=message)
17
- return True
@@ -1,12 +0,0 @@
1
- import sys
2
- from pathlib import Path
3
-
4
- from . import root as git_root
5
-
6
-
7
- def entrypoint() -> Path:
8
- fpath: Path = Path(sys.argv[0]).absolute()
9
- root: Path = git_root()
10
- if fpath.is_relative_to(root):
11
- return fpath.relative_to(root)
12
- return fpath
@@ -1,3 +0,0 @@
1
- from liblaf.grapes.git import GitInfo, info, root, root_safe
2
-
3
- __all__ = ["GitInfo", "info", "root", "root_safe"]
@@ -1,4 +0,0 @@
1
- from ._link import permalink
2
- from ._repo import user_repo
3
-
4
- __all__ = ["permalink", "user_repo"]
@@ -1,25 +0,0 @@
1
- import os
2
- from pathlib import Path
3
-
4
- import git
5
-
6
- from . import user_repo
7
-
8
-
9
- def permalink(
10
- repo: git.Repo | None = None, filepath: str | os.PathLike[str] | None = None
11
- ) -> str | None:
12
- if repo is None:
13
- repo = git.Repo(search_parent_directories=True)
14
- user: str | None
15
- repo_str: str | None
16
- user, repo_str = user_repo(repo)
17
- if not (user and repo):
18
- return None
19
- sha: str = repo.head.commit.hexsha
20
- link: str = f"https://github.com/{user}/{repo_str}/tree/{sha}"
21
- if filepath:
22
- filepath = Path(filepath).absolute()
23
- if not filepath.is_relative_to(repo.working_dir):
24
- return None
25
- link += f"/{Path(filepath).as_posix()}"
@@ -1,23 +0,0 @@
1
- import re
2
-
3
- import git
4
-
5
- GITHUB_URL_PATTERNS: list[str] = [
6
- r"https://github\.com/(?P<user>[^/]+)/(?P<repo>[^/]+)(?:\.git)?"
7
- ]
8
-
9
-
10
- def user_repo(
11
- repo: git.Repo | None = None,
12
- ) -> tuple[str, str] | tuple[None, None]:
13
- if repo is None:
14
- repo = git.Repo(search_parent_directories=True)
15
- remote: git.Remote = repo.remote()
16
- for pattern in GITHUB_URL_PATTERNS:
17
- match: re.Match[str] | None = re.match(pattern, remote.url)
18
- if not match:
19
- continue
20
- user: str = match.group("user")
21
- repo_name: str = match.group("repo")
22
- return user, repo_name
23
- return None, None
@@ -1,5 +0,0 @@
1
- from ._backend import Backend
2
- from ._factory import backend_factory
3
- from ._neptune import BackendNeptune
4
-
5
- __all__ = ["Backend", "BackendNeptune", "backend_factory"]
@@ -1,53 +0,0 @@
1
- import datetime
2
- import functools
3
- from pathlib import Path
4
- from typing import Any
5
-
6
- import pydantic_settings as ps
7
-
8
- from liblaf import cherries
9
-
10
-
11
- class Backend(ps.BaseSettings):
12
- model_config = ps.SettingsConfigDict(
13
- frozen=True, env_prefix=cherries.ENV_PREFIX + "DUMMY_"
14
- )
15
- enabled: bool = True
16
-
17
- @property
18
- def backend(self) -> str:
19
- return "dummy"
20
-
21
- @functools.cached_property
22
- def entrypoint(self) -> Path:
23
- return cherries.entrypoint()
24
-
25
- @property
26
- def id(self) -> str:
27
- raise NotImplementedError
28
-
29
- @property
30
- def name(self) -> str:
31
- raise NotImplementedError
32
-
33
- @functools.cached_property
34
- def start_time(self) -> datetime.datetime:
35
- return datetime.datetime.now().astimezone()
36
-
37
- @property
38
- def url(self) -> str:
39
- raise NotImplementedError
40
-
41
- def start(self) -> None: ...
42
- def end(self) -> None: ...
43
- def log_metric(
44
- self,
45
- key: str,
46
- value: float,
47
- *,
48
- step: float | None = None,
49
- timestamp: float | None = None,
50
- **kwargs,
51
- ) -> None: ...
52
- def log_other(self, key: str, value: Any, **kwargs) -> None: ...
53
- def upload_file(self, key: str, path: Path, **kwargs) -> None: ...
@@ -1,13 +0,0 @@
1
- from liblaf import cherries
2
-
3
-
4
- def backend_factory(backend: str | None = None) -> cherries.Backend:
5
- backend = backend or cherries.env.str("BACKEND", "dummy")
6
- match backend:
7
- case "neptune":
8
- return cherries.BackendNeptune()
9
- case "dummy":
10
- return cherries.Backend()
11
- case _:
12
- msg: str = f"Unknown backend: {backend}"
13
- raise ValueError(msg)
@@ -1,66 +0,0 @@
1
- import os
2
- from pathlib import Path
3
- from typing import Any
4
-
5
- import neptune
6
- import neptune.common.exceptions
7
- import neptune.utils
8
- import pydantic
9
- import pydantic_settings as ps
10
-
11
- from liblaf import cherries
12
-
13
-
14
- class BackendNeptune(cherries.Backend):
15
- model_config = ps.SettingsConfigDict(frozen=True, env_prefix="NEPTUNE_")
16
- monitoring_namespace: str | None = None
17
- _backend: neptune.Run = pydantic.PrivateAttr()
18
-
19
- @property
20
- def backend(self) -> str:
21
- return "neptune"
22
-
23
- @property
24
- def id(self) -> str:
25
- return self._backend["sys/id"].fetch()
26
-
27
- @property
28
- def name(self) -> str:
29
- return self._backend["sys/name"].fetch()
30
-
31
- @property
32
- def url(self) -> str:
33
- return self._backend.get_url()
34
-
35
- def start(self) -> None:
36
- neptune.common.exceptions.STYLES.update(neptune.common.exceptions.EMPTY_STYLES)
37
- self._backend = neptune.init_run(monitoring_namespace=self.monitoring_namespace)
38
-
39
- def end(self) -> None:
40
- self._backend.stop()
41
-
42
- def log_metric(
43
- self,
44
- key: str,
45
- value: float,
46
- *,
47
- step: float | None = None,
48
- timestamp: float | None = None,
49
- **kwargs,
50
- ) -> None:
51
- self._backend[key].append(value, step=step, timestamp=timestamp, **kwargs)
52
-
53
- def log_other(self, key: str, value: Any, **kwargs) -> None:
54
- value = stringify_unsupported(value)
55
- self._backend[key].assign(value, **kwargs)
56
-
57
- def upload_file(self, key: str, path: Path, **kwargs) -> None:
58
- return self._backend[key].upload(str(path), **kwargs)
59
-
60
-
61
- def stringify_unsupported(value: Any) -> Any:
62
- if isinstance(value, pydantic.BaseModel):
63
- return value.model_dump()
64
- if isinstance(value, os.PathLike):
65
- return str(value)
66
- return value
@@ -1,9 +0,0 @@
1
- from liblaf import cherries
2
-
3
-
4
- def default_plugins() -> list[cherries.Plugin]:
5
- return [
6
- cherries.plugin.PluginLogging(),
7
- cherries.plugin.PluginGit(),
8
- cherries.plugin.PluginRestic(),
9
- ]
@@ -1,60 +0,0 @@
1
- import contextlib
2
- import json
3
- import os
4
- import subprocess as sp
5
- from pathlib import Path
6
- from typing import Any
7
-
8
- import pydantic
9
- import pydantic_settings as ps
10
- from loguru import logger
11
-
12
- from liblaf import cherries
13
-
14
-
15
- def default_config() -> Path:
16
- git_root: Path = cherries.git.root()
17
- for path in [
18
- git_root / ".config" / "resticprofile.toml",
19
- git_root / "resticprofile.toml",
20
- ]:
21
- if path.exists():
22
- return path
23
- return git_root / ".config" / "resticprofile.toml"
24
-
25
-
26
- class PluginRestic(cherries.Plugin):
27
- model_config = ps.SettingsConfigDict(env_prefix=cherries.ENV_PREFIX + "RESTIC_")
28
- config: Path = pydantic.Field(default_factory=default_config)
29
- name: str | None = None
30
- dry_run: bool = False
31
-
32
- def _pre_end(self, run: cherries.Experiment) -> None:
33
- if not self.config.exists():
34
- logger.warning("configuration file '{}' was not found", self.config)
35
- return
36
- args: list[str | os.PathLike[str]] = [
37
- "resticprofile",
38
- "--config",
39
- self.config,
40
- "backup",
41
- "--json",
42
- ]
43
- if self.name:
44
- args += ["--name", self.name]
45
- if self.dry_run:
46
- args.append("--dry-run")
47
- args += ["--time", run.start_time.strftime("%Y-%m-%d %H:%M:%S")]
48
- proc: sp.Popen[str] = sp.Popen(
49
- args, stdout=sp.PIPE, cwd=cherries.git.root(), text=True
50
- )
51
- assert proc.stdout is not None
52
- for line_ in proc.stdout:
53
- line: str = line_.rstrip()
54
- logger.debug("{}", line)
55
- with contextlib.suppress(json.JSONDecodeError):
56
- log: dict[str, Any] = json.loads(line)
57
- if log["message_type"] == "summary":
58
- run.log_other("cherries/restic", log)
59
- returncode: int = proc.wait()
60
- run.log_other("cherries/restic/returncode", returncode)
@@ -1,38 +0,0 @@
1
- liblaf/cherries/__init__.py,sha256=OHb6Xou2v6u42swTgjRfzej4CIlRg4OmgOIQXUiRjKA,97
2
- liblaf/cherries/__init__.pyi,sha256=84_e3bkixil-clAuX5MgUHQbDofP_Ylcu1Yeipn4Ycc,860
3
- liblaf/cherries/_config.py,sha256=rm-Y6roi8hBvQYdH-VQh_ovWCyVsX_7R0x1jokBPCDM,741
4
- liblaf/cherries/_env.py,sha256=RK9NMHIok-AkCLMqW44cXLl0d_daLjpEcjhreSP1vm0,92
5
- liblaf/cherries/_experiment.py,sha256=E6r5DyojfY75lKsIDxYpyaCgXFXMJTaUIglIk9Xs-Sw,3181
6
- liblaf/cherries/_main.py,sha256=R8vWc9e94MViqCzMiG257--QtSoOU50lmR59oIRc6nw,1237
7
- liblaf/cherries/_run.py,sha256=zQrC2fzpbHtT6M3E9gGoYVPFsWeKYkMG5MEFwZ695vo,731
8
- liblaf/cherries/_start.py,sha256=iGAhDm8sF_JCaWPWdMIFL0d5nODFU8IcBPdNihhiSp4,685
9
- liblaf/cherries/_version.py,sha256=J0-psBAr052UgYPFe4_RoTpIwBL8wFdIM3d_qC8JwcE,511
10
- liblaf/cherries/_version.pyi,sha256=Pnv4Bxw13LHeuVkPLPsTtnp4N4jOGcAfFJw05uMMgBY,108
11
- liblaf/cherries/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- liblaf/cherries/git/__init__.py,sha256=OHb6Xou2v6u42swTgjRfzej4CIlRg4OmgOIQXUiRjKA,97
13
- liblaf/cherries/git/__init__.pyi,sha256=kHd7B4_atL4929so2AnrBcCJNgGg-i-HEi4PeGh3csk,383
14
- liblaf/cherries/git/_commit.py,sha256=jnAtCKljNnzhXK90cj3adAYkPvcnLnOrHWA8YWhtZF4,482
15
- liblaf/cherries/git/_entrypoint.py,sha256=My_TmLqpGX4NJV4qjQvmHtnwhxX_B2ilfuYvpj2ftaM,262
16
- liblaf/cherries/git/_grapes.py,sha256=f9RRn2ci-fC5FqkbPJoIjNcJpUMwo2qBeu7CMre_t1o,113
17
- liblaf/cherries/git/github/__init__.py,sha256=OHb6Xou2v6u42swTgjRfzej4CIlRg4OmgOIQXUiRjKA,97
18
- liblaf/cherries/git/github/__init__.pyi,sha256=jspOamBde7EtGOqsIzWg75jFToVHRhG4hfiEw1MDz80,96
19
- liblaf/cherries/git/github/_link.py,sha256=f_AcdKMhukUZ2fgBtC0usBrwnpAHaLYo9EhkZYesZuQ,693
20
- liblaf/cherries/git/github/_repo.py,sha256=I3vjgonI_SPrytf68qzLAej880Zn7cPryaK4PPoVZpU,627
21
- liblaf/cherries/integration/__init__.py,sha256=OHb6Xou2v6u42swTgjRfzej4CIlRg4OmgOIQXUiRjKA,97
22
- liblaf/cherries/integration/__init__.pyi,sha256=n2QqtCl9oTVJatyt8LhiTJVnr_uoyYgfrN8virEqezQ,165
23
- liblaf/cherries/integration/_backend.py,sha256=iwpwTB3NgAI9oUCdWYMmH8qI8xYmUsZmES0pyw9_6D0,1241
24
- liblaf/cherries/integration/_factory.py,sha256=KJPse2efpOLv6s4sPQAPnzh9vwYcIQVsOg1ucxzTmIo,412
25
- liblaf/cherries/integration/_neptune.py,sha256=MhvPZUblAae6vmGRjgDELl_2wcOhrb90nCIsg8xpRMs,1789
26
- liblaf/cherries/plugin/__init__.py,sha256=OHb6Xou2v6u42swTgjRfzej4CIlRg4OmgOIQXUiRjKA,97
27
- liblaf/cherries/plugin/__init__.pyi,sha256=3wmkKoe27SI3q5zbyejf3KmaBRUhAu-OEefJAxxbECs,248
28
- liblaf/cherries/plugin/_abc.py,sha256=kMDFzDAEDifpxWbnQhp4M4sr24-D55x-B6MPIZW_1jA,848
29
- liblaf/cherries/plugin/_default.py,sha256=H7_vym_uxxba41xR2ERBeBt0kBX4s4tjzjifyKjXxS0,215
30
- liblaf/cherries/plugin/_git.py,sha256=aZeqBdRRG8rHaSFoj1lGMEvtFk6dDKhV6nMahx5EOn8,867
31
- liblaf/cherries/plugin/_logging.py,sha256=cLDQMongbRAwJjW5GAmRRzvuF2rK4GNTAHHkJCJh71k,1262
32
- liblaf/cherries/plugin/_restic.py,sha256=4ArmgD42ZUotkVdCwdMvlmJF0Z8PuKe8EukzRoWyQK8,1926
33
- liblaf/cherries/utils/__init__.py,sha256=OHb6Xou2v6u42swTgjRfzej4CIlRg4OmgOIQXUiRjKA,97
34
- liblaf/cherries/utils/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
- liblaf_cherries-0.0.9.dist-info/METADATA,sha256=4r3X50j5n2EBtM2AwEOOho5yNDXOhffqGdSGnw0P0Kk,1870
36
- liblaf_cherries-0.0.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
37
- liblaf_cherries-0.0.9.dist-info/licenses/LICENSE,sha256=Ph4NzyU3lGVDeYv-mf8aRmImH8v9rVL9F362FV4G6Ow,1063
38
- liblaf_cherries-0.0.9.dist-info/RECORD,,
File without changes
File without changes
File without changes