hydraflow 0.12.2__py3-none-any.whl → 0.12.4__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.
- hydraflow/cli.py +10 -6
- hydraflow/core/context.py +4 -2
- hydraflow/core/io.py +36 -12
- hydraflow/core/main.py +7 -6
- hydraflow/core/mlflow.py +8 -2
- hydraflow/entities/run_collection.py +4 -2
- hydraflow/entities/run_data.py +4 -2
- {hydraflow-0.12.2.dist-info → hydraflow-0.12.4.dist-info}/METADATA +1 -1
- {hydraflow-0.12.2.dist-info → hydraflow-0.12.4.dist-info}/RECORD +12 -12
- {hydraflow-0.12.2.dist-info → hydraflow-0.12.4.dist-info}/WHEEL +0 -0
- {hydraflow-0.12.2.dist-info → hydraflow-0.12.4.dist-info}/entry_points.txt +0 -0
- {hydraflow-0.12.2.dist-info → hydraflow-0.12.4.dist-info}/licenses/LICENSE +0 -0
hydraflow/cli.py
CHANGED
@@ -8,8 +8,6 @@ import typer
|
|
8
8
|
from rich.console import Console
|
9
9
|
from typer import Argument, Option
|
10
10
|
|
11
|
-
from hydraflow.executor.io import get_job, load_config
|
12
|
-
|
13
11
|
app = typer.Typer(add_completion=False)
|
14
12
|
console = Console()
|
15
13
|
|
@@ -24,16 +22,20 @@ def run(
|
|
24
22
|
] = False,
|
25
23
|
) -> None:
|
26
24
|
"""Run a job."""
|
27
|
-
import mlflow
|
28
25
|
|
26
|
+
from hydraflow.executor.io import get_job
|
29
27
|
from hydraflow.executor.job import multirun, to_text
|
30
28
|
|
31
29
|
job = get_job(name)
|
30
|
+
|
32
31
|
if dry_run:
|
33
32
|
typer.echo(to_text(job))
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
raise typer.Exit
|
34
|
+
|
35
|
+
import mlflow
|
36
|
+
|
37
|
+
mlflow.set_experiment(job.name)
|
38
|
+
multirun(job)
|
37
39
|
|
38
40
|
|
39
41
|
@app.command()
|
@@ -43,6 +45,8 @@ def show(
|
|
43
45
|
"""Show the hydraflow config."""
|
44
46
|
from omegaconf import OmegaConf
|
45
47
|
|
48
|
+
from hydraflow.executor.io import get_job, load_config
|
49
|
+
|
46
50
|
if name:
|
47
51
|
cfg = get_job(name)
|
48
52
|
else:
|
hydraflow/core/context.py
CHANGED
@@ -8,8 +8,6 @@ from contextlib import contextmanager
|
|
8
8
|
from pathlib import Path
|
9
9
|
from typing import TYPE_CHECKING
|
10
10
|
|
11
|
-
import mlflow
|
12
|
-
import mlflow.artifacts
|
13
11
|
from hydra.core.hydra_config import HydraConfig
|
14
12
|
|
15
13
|
from hydraflow.core.io import get_artifact_dir
|
@@ -52,6 +50,8 @@ def log_run(
|
|
52
50
|
```
|
53
51
|
|
54
52
|
"""
|
53
|
+
import mlflow
|
54
|
+
|
55
55
|
if config:
|
56
56
|
log_params(config, synchronous=synchronous)
|
57
57
|
|
@@ -114,6 +114,8 @@ def start_run(
|
|
114
114
|
Run: An MLflow Run object representing the started run.
|
115
115
|
|
116
116
|
"""
|
117
|
+
import mlflow
|
118
|
+
|
117
119
|
with (
|
118
120
|
mlflow.start_run(
|
119
121
|
run_id=run_id,
|
hydraflow/core/io.py
CHANGED
@@ -8,14 +8,13 @@ import urllib.request
|
|
8
8
|
from pathlib import Path
|
9
9
|
from typing import TYPE_CHECKING
|
10
10
|
|
11
|
-
import mlflow
|
12
|
-
import mlflow.artifacts
|
13
11
|
from hydra.core.hydra_config import HydraConfig
|
14
|
-
from mlflow.entities import Run
|
15
12
|
from omegaconf import DictConfig, ListConfig, OmegaConf
|
16
13
|
|
17
14
|
if TYPE_CHECKING:
|
18
|
-
from collections.abc import Iterable, Iterator
|
15
|
+
from collections.abc import Callable, Iterable, Iterator
|
16
|
+
|
17
|
+
from mlflow.entities import Run
|
19
18
|
|
20
19
|
|
21
20
|
def file_uri_to_path(uri: str) -> Path:
|
@@ -39,6 +38,8 @@ def get_artifact_dir(run: Run | None = None) -> Path:
|
|
39
38
|
The local path to the directory where the artifacts are downloaded.
|
40
39
|
|
41
40
|
"""
|
41
|
+
import mlflow
|
42
|
+
|
42
43
|
if run is None:
|
43
44
|
uri = mlflow.get_artifact_uri()
|
44
45
|
else:
|
@@ -141,6 +142,8 @@ def load_overrides(run: Run) -> ListConfig:
|
|
141
142
|
|
142
143
|
def remove_run(run: Run | Iterable[Run]) -> None:
|
143
144
|
"""Remove the given run from the MLflow tracking server."""
|
145
|
+
from mlflow.entities import Run
|
146
|
+
|
144
147
|
if not isinstance(run, Run):
|
145
148
|
for r in run:
|
146
149
|
remove_run(r)
|
@@ -151,6 +154,8 @@ def remove_run(run: Run | Iterable[Run]) -> None:
|
|
151
154
|
|
152
155
|
def get_root_dir(uri: str | Path | None = None) -> Path:
|
153
156
|
"""Get the root directory for the MLflow tracking server."""
|
157
|
+
import mlflow
|
158
|
+
|
154
159
|
if uri is not None:
|
155
160
|
return Path(uri).absolute()
|
156
161
|
|
@@ -174,8 +179,29 @@ def get_experiment_name(path: Path) -> str | None:
|
|
174
179
|
return None
|
175
180
|
|
176
181
|
|
182
|
+
def predicate_experiment_dir(
|
183
|
+
path: Path,
|
184
|
+
experiment_names: list[str] | Callable[[str], bool] | None = None,
|
185
|
+
) -> bool:
|
186
|
+
"""Predicate an experiment directory based on the path and experiment names."""
|
187
|
+
if not path.is_dir() or path.name in [".trash", "0"]:
|
188
|
+
return False
|
189
|
+
|
190
|
+
name = get_experiment_name(path)
|
191
|
+
if not name:
|
192
|
+
return False
|
193
|
+
|
194
|
+
if experiment_names is None:
|
195
|
+
return True
|
196
|
+
|
197
|
+
if isinstance(experiment_names, list):
|
198
|
+
return name in experiment_names
|
199
|
+
|
200
|
+
return experiment_names(name)
|
201
|
+
|
202
|
+
|
177
203
|
def iter_experiment_dirs(
|
178
|
-
experiment_names: str | list[str] | None = None,
|
204
|
+
experiment_names: str | list[str] | Callable[[str], bool] | None = None,
|
179
205
|
root_dir: str | Path | None = None,
|
180
206
|
) -> Iterator[Path]:
|
181
207
|
"""Iterate over the experiment directories in the root directory."""
|
@@ -184,14 +210,12 @@ def iter_experiment_dirs(
|
|
184
210
|
|
185
211
|
root_dir = get_root_dir(root_dir)
|
186
212
|
for path in root_dir.iterdir():
|
187
|
-
if
|
188
|
-
|
189
|
-
if experiment_names is None or name in experiment_names:
|
190
|
-
yield path
|
213
|
+
if predicate_experiment_dir(path, experiment_names):
|
214
|
+
yield path
|
191
215
|
|
192
216
|
|
193
217
|
def iter_run_dirs(
|
194
|
-
experiment_names: str | list[str] | None = None,
|
218
|
+
experiment_names: str | list[str] | Callable[[str], bool] | None = None,
|
195
219
|
root_dir: str | Path | None = None,
|
196
220
|
) -> Iterator[Path]:
|
197
221
|
"""Iterate over the run directories in the root directory."""
|
@@ -202,7 +226,7 @@ def iter_run_dirs(
|
|
202
226
|
|
203
227
|
|
204
228
|
def iter_artifacts_dirs(
|
205
|
-
experiment_names: str | list[str] | None = None,
|
229
|
+
experiment_names: str | list[str] | Callable[[str], bool] | None = None,
|
206
230
|
root_dir: str | Path | None = None,
|
207
231
|
) -> Iterator[Path]:
|
208
232
|
"""Iterate over the artifacts directories in the root directory."""
|
@@ -212,7 +236,7 @@ def iter_artifacts_dirs(
|
|
212
236
|
|
213
237
|
def iter_artifact_paths(
|
214
238
|
artifact_path: str | Path,
|
215
|
-
experiment_names: str | list[str] | None = None,
|
239
|
+
experiment_names: str | list[str] | Callable[[str], bool] | None = None,
|
216
240
|
root_dir: str | Path | None = None,
|
217
241
|
) -> Iterator[Path]:
|
218
242
|
"""Iterate over the artifact paths in the root directory."""
|
hydraflow/core/main.py
CHANGED
@@ -39,13 +39,11 @@ from functools import wraps
|
|
39
39
|
from typing import TYPE_CHECKING, TypeVar
|
40
40
|
|
41
41
|
import hydra
|
42
|
-
import mlflow
|
43
42
|
from hydra.core.config_store import ConfigStore
|
44
43
|
from hydra.core.hydra_config import HydraConfig
|
45
|
-
from mlflow.entities import RunStatus
|
46
44
|
from omegaconf import OmegaConf
|
47
45
|
|
48
|
-
import
|
46
|
+
from hydraflow.core.context import start_run
|
49
47
|
from hydraflow.core.io import file_uri_to_path
|
50
48
|
|
51
49
|
if TYPE_CHECKING:
|
@@ -55,7 +53,6 @@ if TYPE_CHECKING:
|
|
55
53
|
|
56
54
|
from mlflow.entities import Run
|
57
55
|
|
58
|
-
FINISHED = RunStatus.to_string(RunStatus.FINISHED)
|
59
56
|
|
60
57
|
T = TypeVar("T")
|
61
58
|
|
@@ -88,6 +85,10 @@ def main(
|
|
88
85
|
False.
|
89
86
|
|
90
87
|
"""
|
88
|
+
import mlflow
|
89
|
+
from mlflow.entities import RunStatus
|
90
|
+
|
91
|
+
finished = RunStatus.to_string(RunStatus.FINISHED)
|
91
92
|
|
92
93
|
def decorator(app: Callable[[Run, T], None]) -> Callable[[], None]:
|
93
94
|
ConfigStore.instance().store(config_name, node)
|
@@ -107,10 +108,10 @@ def main(
|
|
107
108
|
|
108
109
|
if run_id and not rerun_finished:
|
109
110
|
run = mlflow.get_run(run_id)
|
110
|
-
if run.info.status ==
|
111
|
+
if run.info.status == finished:
|
111
112
|
return
|
112
113
|
|
113
|
-
with
|
114
|
+
with start_run(config, run_id=run_id, chdir=chdir) as run:
|
114
115
|
app(run, config)
|
115
116
|
|
116
117
|
return inner_decorator
|
hydraflow/core/mlflow.py
CHANGED
@@ -10,8 +10,6 @@ from __future__ import annotations
|
|
10
10
|
from typing import TYPE_CHECKING
|
11
11
|
|
12
12
|
import joblib
|
13
|
-
import mlflow
|
14
|
-
import mlflow.artifacts
|
15
13
|
|
16
14
|
from hydraflow.core.io import file_uri_to_path, get_artifact_dir
|
17
15
|
from hydraflow.entities.run_collection import RunCollection
|
@@ -36,6 +34,8 @@ def log_params(config: Any, *, synchronous: bool | None = None) -> None:
|
|
36
34
|
Defaults to None.
|
37
35
|
|
38
36
|
"""
|
37
|
+
import mlflow
|
38
|
+
|
39
39
|
for key, value in iter_params(config):
|
40
40
|
mlflow.log_param(key, value, synchronous=synchronous)
|
41
41
|
|
@@ -50,6 +50,8 @@ def log_text(from_dir: Path, pattern: str = "*.log") -> None:
|
|
50
50
|
pattern (str): The pattern to match the logs.
|
51
51
|
|
52
52
|
"""
|
53
|
+
import mlflow
|
54
|
+
|
53
55
|
artifact_dir = get_artifact_dir()
|
54
56
|
|
55
57
|
for file in from_dir.glob(pattern):
|
@@ -88,6 +90,8 @@ def list_run_paths(
|
|
88
90
|
list[Path]: A list of run paths for the specified experiments.
|
89
91
|
|
90
92
|
"""
|
93
|
+
import mlflow
|
94
|
+
|
91
95
|
if isinstance(experiment_names, str):
|
92
96
|
experiment_names = [experiment_names]
|
93
97
|
|
@@ -155,6 +159,8 @@ def list_runs(
|
|
155
159
|
specified experiments.
|
156
160
|
|
157
161
|
"""
|
162
|
+
import mlflow
|
163
|
+
|
158
164
|
run_ids = list_run_ids(experiment_names)
|
159
165
|
|
160
166
|
if n_jobs == 0:
|
@@ -23,8 +23,6 @@ from dataclasses import dataclass, field
|
|
23
23
|
from itertools import chain
|
24
24
|
from typing import TYPE_CHECKING, Any, overload
|
25
25
|
|
26
|
-
from mlflow.entities import RunStatus
|
27
|
-
|
28
26
|
import hydraflow.core.param
|
29
27
|
from hydraflow.core.config import iter_params, select_config, select_overrides
|
30
28
|
from hydraflow.core.io import load_config
|
@@ -560,6 +558,8 @@ def filter_runs_by_status(
|
|
560
558
|
A list of runs that match the specified status.
|
561
559
|
|
562
560
|
"""
|
561
|
+
from mlflow.entities import RunStatus
|
562
|
+
|
563
563
|
if isinstance(status, str):
|
564
564
|
if status.startswith("!"):
|
565
565
|
status = status[1:].lower()
|
@@ -575,6 +575,8 @@ def filter_runs_by_status(
|
|
575
575
|
|
576
576
|
|
577
577
|
def _to_lower(status: str | int) -> str:
|
578
|
+
from mlflow.entities import RunStatus
|
579
|
+
|
578
580
|
if isinstance(status, str):
|
579
581
|
return status.lower()
|
580
582
|
|
hydraflow/entities/run_data.py
CHANGED
@@ -4,8 +4,6 @@ from __future__ import annotations
|
|
4
4
|
|
5
5
|
from typing import TYPE_CHECKING
|
6
6
|
|
7
|
-
from pandas import DataFrame
|
8
|
-
|
9
7
|
from hydraflow.core.config import iter_params
|
10
8
|
from hydraflow.core.io import load_config
|
11
9
|
|
@@ -13,6 +11,8 @@ if TYPE_CHECKING:
|
|
13
11
|
from collections.abc import Iterable
|
14
12
|
from typing import Any
|
15
13
|
|
14
|
+
from pandas import DataFrame
|
15
|
+
|
16
16
|
from .run_collection import RunCollection
|
17
17
|
|
18
18
|
|
@@ -40,6 +40,8 @@ class RunCollectionData:
|
|
40
40
|
A DataFrame containing the runs' configurations.
|
41
41
|
|
42
42
|
"""
|
43
|
+
from pandas import DataFrame
|
44
|
+
|
43
45
|
values = [dict(iter_params(load_config(r))) for r in self._runs]
|
44
46
|
return DataFrame(values)
|
45
47
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: hydraflow
|
3
|
-
Version: 0.12.
|
3
|
+
Version: 0.12.4
|
4
4
|
Summary: Hydraflow integrates Hydra and MLflow to manage and track machine learning experiments.
|
5
5
|
Project-URL: Documentation, https://daizutabi.github.io/hydraflow/
|
6
6
|
Project-URL: Source, https://github.com/daizutabi/hydraflow
|
@@ -1,24 +1,24 @@
|
|
1
1
|
hydraflow/__init__.py,sha256=f2KO2iF7um-nNmayNyEr7TWG4UICOXy7YAN1d3qu0OY,936
|
2
|
-
hydraflow/cli.py,sha256=
|
2
|
+
hydraflow/cli.py,sha256=clQ7PD_okuGhbrgQ0q8Ldbb8xY3u3He5hI_uBI4h1Q4,1470
|
3
3
|
hydraflow/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
4
|
hydraflow/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
5
|
hydraflow/core/config.py,sha256=SJzjgsO_kzB78_whJ3lmy7GlZvTvwZONH1BJBn8zCuI,3817
|
6
|
-
hydraflow/core/context.py,sha256=
|
7
|
-
hydraflow/core/io.py,sha256=
|
8
|
-
hydraflow/core/main.py,sha256=
|
9
|
-
hydraflow/core/mlflow.py,sha256=
|
6
|
+
hydraflow/core/context.py,sha256=L4OygMLbITwlWzq17Lh8VoXKKtjOJ3DBEVsBddKPSJ8,4741
|
7
|
+
hydraflow/core/io.py,sha256=6ZQYqxPUkIinFYqSQXJPzTSnuhfP1KfFchTNeNn-g6A,7311
|
8
|
+
hydraflow/core/main.py,sha256=dY8uUykS_AbzverrSWkXLyj98TjBPHAiMUf_l5met1U,5162
|
9
|
+
hydraflow/core/mlflow.py,sha256=OQJ3f2wkHJRb11ZK__HF4R8FyBEje7-NOqObpoanGhU,5704
|
10
10
|
hydraflow/core/param.py,sha256=LHU9j9_7oA99igasoOyKofKClVr9FmGA3UABJ-KmyS0,4538
|
11
11
|
hydraflow/entities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
12
|
-
hydraflow/entities/run_collection.py,sha256=
|
13
|
-
hydraflow/entities/run_data.py,sha256=
|
12
|
+
hydraflow/entities/run_collection.py,sha256=4sfZWXaS7kqnVCo9GyB3pN6BaSUCkA-ZqSSl5JBLNhk,19682
|
13
|
+
hydraflow/entities/run_data.py,sha256=lz8HPxG0iz1Jf9FU6HTFW4gcAc3N2pgMyAPqAIK6I74,1644
|
14
14
|
hydraflow/entities/run_info.py,sha256=FRC6ICOlzB2u_xi_33Qs-YZLt677UotuNbYqI7XSmHY,1017
|
15
15
|
hydraflow/executor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
16
16
|
hydraflow/executor/conf.py,sha256=2dv6_PlsynRmia-fGZlmBEVt8GopT0f32N13qY7tYnM,402
|
17
17
|
hydraflow/executor/io.py,sha256=yZMcBVmAbPZZ82cAXhgiJfj9p8WvHmzOCMBg_vtEVek,1509
|
18
18
|
hydraflow/executor/job.py,sha256=IL7ek0Vwa3Bl_gANq0wCbldNCUclo8YBckeEeO6W6xg,4852
|
19
19
|
hydraflow/executor/parser.py,sha256=_Rfund3FDgrXitTt_znsTpgEtMDqZ_ICynaB_Zje14Q,14561
|
20
|
-
hydraflow-0.12.
|
21
|
-
hydraflow-0.12.
|
22
|
-
hydraflow-0.12.
|
23
|
-
hydraflow-0.12.
|
24
|
-
hydraflow-0.12.
|
20
|
+
hydraflow-0.12.4.dist-info/METADATA,sha256=CT9bb--1HhyO_tcahfCTzSUBH2nWt7i2lY2pS3Dac38,4549
|
21
|
+
hydraflow-0.12.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
22
|
+
hydraflow-0.12.4.dist-info/entry_points.txt,sha256=XI0khPbpCIUo9UPqkNEpgh-kqK3Jy8T7L2VCWOdkbSM,48
|
23
|
+
hydraflow-0.12.4.dist-info/licenses/LICENSE,sha256=IGdDrBPqz1O0v_UwCW-NJlbX9Hy9b3uJ11t28y2srmY,1062
|
24
|
+
hydraflow-0.12.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|