hydraflow 0.5.4__py3-none-any.whl → 0.6.1__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/__init__.py CHANGED
@@ -1,7 +1,7 @@
1
1
  """Integrate Hydra and MLflow to manage and track machine learning experiments."""
2
2
 
3
3
  from .config import select_config, select_overrides
4
- from .context import chdir_artifact, chdir_hydra_output, log_run, start_run
4
+ from .context import chdir_artifact, log_run, start_run
5
5
  from .mlflow import list_runs, search_runs, set_experiment
6
6
  from .run_collection import RunCollection
7
7
  from .utils import (
@@ -17,7 +17,6 @@ from .utils import (
17
17
  __all__ = [
18
18
  "RunCollection",
19
19
  "chdir_artifact",
20
- "chdir_hydra_output",
21
20
  "get_artifact_dir",
22
21
  "get_artifact_path",
23
22
  "get_hydra_output_dir",
hydraflow/config.py CHANGED
@@ -22,6 +22,7 @@ def collect_params(config: object) -> dict[str, Any]:
22
22
 
23
23
  Returns:
24
24
  dict[str, Any]: A dictionary of collected parameters.
25
+
25
26
  """
26
27
  return dict(iter_params(config))
27
28
 
@@ -40,6 +41,7 @@ def iter_params(config: object, prefix: str = "") -> Iterator[tuple[str, Any]]:
40
41
 
41
42
  Yields:
42
43
  Key-value pairs representing the parameters in the configuration object.
44
+
43
45
  """
44
46
  if config is None:
45
47
  return
@@ -113,6 +115,7 @@ def select_config(config: object, names: list[str]) -> dict[str, Any]:
113
115
 
114
116
  Returns:
115
117
  DictConfig: A new configuration object containing only the selected parameters.
118
+
116
119
  """
117
120
  if not isinstance(config, DictConfig):
118
121
  config = OmegaConf.structured(config)
hydraflow/context.py CHANGED
@@ -13,6 +13,7 @@ import mlflow.artifacts
13
13
  from hydra.core.hydra_config import HydraConfig
14
14
 
15
15
  from hydraflow.mlflow import log_params
16
+ from hydraflow.utils import get_artifact_dir
16
17
 
17
18
  if TYPE_CHECKING:
18
19
  from collections.abc import Iterator
@@ -48,6 +49,7 @@ def log_run(
48
49
  # Perform operations within the MLflow run context
49
50
  pass
50
51
  ```
52
+
51
53
  """
52
54
  if config:
53
55
  log_params(config, synchronous=synchronous)
@@ -55,7 +57,7 @@ def log_run(
55
57
  hc = HydraConfig.get()
56
58
  output_dir = Path(hc.runtime.output_dir)
57
59
 
58
- # Save '.hydra' config directory first.
60
+ # Save '.hydra' config directory.
59
61
  output_subdir = output_dir / (hc.output_subdir or "")
60
62
  mlflow.log_artifacts(output_subdir.as_posix(), hc.output_subdir)
61
63
 
@@ -68,14 +70,43 @@ def log_run(
68
70
  raise
69
71
 
70
72
  finally:
71
- # Save output_dir including '.hydra' config directory.
72
- mlflow.log_artifacts(output_dir.as_posix())
73
+ log_text(output_dir)
74
+
75
+
76
+ def log_text(directory: Path, pattern: str = "*.log") -> None:
77
+ """Log text files in the given directory as artifacts.
78
+
79
+ Append the text files to the existing text file in the artifact directory.
80
+
81
+ Args:
82
+ directory (Path): The directory to find the logs in.
83
+ pattern (str): The pattern to match the logs.
84
+
85
+ """
86
+ artifact_dir = get_artifact_dir()
87
+
88
+ for file in directory.glob(pattern):
89
+ if not file.is_file():
90
+ continue
91
+
92
+ file_artifact = artifact_dir / file.name
93
+ if file_artifact.exists():
94
+ text = file_artifact.read_text()
95
+ if not text.endswith("\n"):
96
+ text += "\n"
97
+ else:
98
+ text = ""
99
+
100
+ text += file.read_text()
101
+ mlflow.log_text(text, file.name)
73
102
 
74
103
 
75
104
  @contextmanager
76
105
  def start_run( # noqa: PLR0913
77
106
  config: object,
78
107
  *,
108
+ chdir: bool = False,
109
+ run: Run | None = None,
79
110
  run_id: str | None = None,
80
111
  experiment_id: str | None = None,
81
112
  run_name: str | None = None,
@@ -93,6 +124,9 @@ def start_run( # noqa: PLR0913
93
124
 
94
125
  Args:
95
126
  config (object): The configuration object to log parameters from.
127
+ chdir (bool): Whether to change the current working directory to the
128
+ artifact directory of the current run. Defaults to False.
129
+ run (Run | None): The existing run. Defaults to None.
96
130
  run_id (str | None): The existing run ID. Defaults to None.
97
131
  experiment_id (str | None): The experiment ID. Defaults to None.
98
132
  run_name (str | None): The name of the run. Defaults to None.
@@ -117,7 +151,11 @@ def start_run( # noqa: PLR0913
117
151
  - `mlflow.start_run`: The MLflow function to start a run directly.
118
152
  - `log_run`: A context manager to log parameters and manage the MLflow
119
153
  run context.
154
+
120
155
  """
156
+ if run:
157
+ run_id = run.info.run_id
158
+
121
159
  with (
122
160
  mlflow.start_run(
123
161
  run_id=run_id,
@@ -131,33 +169,15 @@ def start_run( # noqa: PLR0913
131
169
  ) as run,
132
170
  log_run(config if run_id is None else None, synchronous=synchronous),
133
171
  ):
134
- yield run
172
+ if chdir:
173
+ with chdir_artifact(run):
174
+ yield run
175
+ else:
176
+ yield run
135
177
 
136
178
 
137
179
  @contextmanager
138
- def chdir_hydra_output() -> Iterator[Path]:
139
- """Change the current working directory to the hydra output directory.
140
-
141
- This context manager changes the current working directory to the hydra output
142
- directory. It ensures that the directory is changed back to the original
143
- directory after the context is exited.
144
- """
145
- curdir = Path.cwd()
146
- path = HydraConfig.get().runtime.output_dir
147
-
148
- os.chdir(path)
149
- try:
150
- yield Path(path)
151
-
152
- finally:
153
- os.chdir(curdir)
154
-
155
-
156
- @contextmanager
157
- def chdir_artifact(
158
- run: Run,
159
- artifact_path: str | None = None,
160
- ) -> Iterator[Path]:
180
+ def chdir_artifact(run: Run | None = None) -> Iterator[Path]:
161
181
  """Change the current working directory to the artifact directory of the given run.
162
182
 
163
183
  This context manager changes the current working directory to the artifact
@@ -165,18 +185,16 @@ def chdir_artifact(
165
185
  to the original directory after the context is exited.
166
186
 
167
187
  Args:
168
- run (Run): The run to get the artifact directory from.
169
- artifact_path (str | None): The artifact path.
188
+ run (Run | None): The run to get the artifact directory from.
189
+
170
190
  """
171
191
  curdir = Path.cwd()
172
- path = mlflow.artifacts.download_artifacts(
173
- run_id=run.info.run_id,
174
- artifact_path=artifact_path,
175
- )
192
+ artifact_dir = get_artifact_dir(run)
193
+
194
+ os.chdir(artifact_dir)
176
195
 
177
- os.chdir(path)
178
196
  try:
179
- yield Path(path)
197
+ yield artifact_dir
180
198
 
181
199
  finally:
182
200
  os.chdir(curdir)
hydraflow/mlflow.py CHANGED
@@ -16,7 +16,6 @@ Key Features:
16
16
 
17
17
  from __future__ import annotations
18
18
 
19
- from pathlib import Path
20
19
  from typing import TYPE_CHECKING
21
20
 
22
21
  import joblib
@@ -28,8 +27,11 @@ from mlflow.tracking.fluent import SEARCH_MAX_RESULTS_PANDAS, _get_experiment_id
28
27
 
29
28
  from hydraflow.config import iter_params
30
29
  from hydraflow.run_collection import RunCollection
30
+ from hydraflow.utils import get_artifact_dir
31
31
 
32
32
  if TYPE_CHECKING:
33
+ from pathlib import Path
34
+
33
35
  from mlflow.entities.experiment import Experiment
34
36
 
35
37
 
@@ -54,6 +56,7 @@ def set_experiment(
54
56
  Returns:
55
57
  Experiment: An instance of `mlflow.entities.Experiment` representing
56
58
  the new active experiment.
59
+
57
60
  """
58
61
  if uri is not None:
59
62
  mlflow.set_tracking_uri(uri)
@@ -77,6 +80,7 @@ def log_params(config: object, *, synchronous: bool | None = None) -> None:
77
80
  config (object): The configuration object to log the parameters from.
78
81
  synchronous (bool | None): Whether to log the parameters synchronously.
79
82
  Defaults to None.
83
+
80
84
  """
81
85
  for key, value in iter_params(config):
82
86
  mlflow.log_param(key, value, synchronous=synchronous)
@@ -133,6 +137,7 @@ def search_runs( # noqa: PLR0913
133
137
 
134
138
  Returns:
135
139
  A `RunCollection` object containing the search results.
140
+
136
141
  """
137
142
  runs = mlflow.search_runs(
138
143
  experiment_ids=experiment_ids,
@@ -177,6 +182,7 @@ def list_runs(
177
182
  Returns:
178
183
  RunCollection: A `RunCollection` instance containing the runs for the
179
184
  specified experiments.
185
+
180
186
  """
181
187
  rc = _list_runs(experiment_names, n_jobs)
182
188
  if status is None:
@@ -207,16 +213,10 @@ def _list_runs(
207
213
 
208
214
  for name in experiment_names:
209
215
  if experiment := mlflow.get_experiment_by_name(name):
210
- loc = experiment.artifact_location
211
-
212
- if isinstance(loc, str):
213
- if loc.startswith("file:"):
214
- path = Path(mlflow.artifacts.download_artifacts(loc))
215
- elif Path(loc).is_dir():
216
- path = Path(loc)
217
- else:
218
- continue # no cov
216
+ uri = experiment.artifact_location
219
217
 
218
+ if isinstance(uri, str):
219
+ path = get_artifact_dir(uri=uri)
220
220
  run_ids.extend(file.stem for file in path.iterdir() if file.is_dir())
221
221
 
222
222
  it = (joblib.delayed(mlflow.get_run)(run_id) for run_id in run_ids)
hydraflow/param.py CHANGED
@@ -28,6 +28,7 @@ def match(param: str, value: Any) -> bool: # noqa: PLR0911
28
28
  Returns:
29
29
  True if the parameter matches the specified value,
30
30
  False otherwise.
31
+
31
32
  """
32
33
  if callable(value):
33
34
  return value(param)
@@ -94,6 +95,7 @@ def to_value(param: str | None, type_: type) -> Any:
94
95
 
95
96
  Returns:
96
97
  The converted value.
98
+
97
99
  """
98
100
  if param is None or param == "None":
99
101
  return None
@@ -129,6 +131,7 @@ def get_params(run: Run, *names: str | list[str]) -> tuple[str | None, ...]:
129
131
  Returns:
130
132
  tuple[str | None, ...]: A tuple containing the values of the specified
131
133
  parameters in the order they were provided.
134
+
132
135
  """
133
136
  names_ = []
134
137
  for name in names:
@@ -155,6 +158,7 @@ def get_values(run: Run, names: list[str], types: list[type]) -> tuple[Any, ...]
155
158
  Returns:
156
159
  tuple[Any, ...]: A tuple containing the values of the specified
157
160
  parameters in the order they were provided.
161
+
158
162
  """
159
163
  params = get_params(run, names)
160
164
  it = zip(params, types, strict=True)
@@ -106,6 +106,7 @@ class RunCollection:
106
106
 
107
107
  Returns:
108
108
  A new `RunCollection` instance with the runs from both collections.
109
+
109
110
  """
110
111
  return self.__class__(self._runs + other._runs)
111
112
 
@@ -118,6 +119,7 @@ class RunCollection:
118
119
  Returns:
119
120
  A new `RunCollection` instance with the runs that are in this collection
120
121
  but not in the other.
122
+
121
123
  """
122
124
  runs = [run for run in self._runs if run not in other._runs] # noqa: SLF001
123
125
  return self.__class__(runs)
@@ -150,6 +152,7 @@ class RunCollection:
150
152
  Returns:
151
153
  A new `RunCollection` instance containing the first n runs if n is
152
154
  positive, or the last n runs if n is negative.
155
+
153
156
  """
154
157
  if n < 0:
155
158
  return self.__class__(self._runs[n:])
@@ -164,6 +167,7 @@ class RunCollection:
164
167
 
165
168
  Raises:
166
169
  ValueError: If the collection does not contain exactly one run.
170
+
167
171
  """
168
172
  if len(self._runs) != 1:
169
173
  raise ValueError("The collection does not contain exactly one run.")
@@ -176,6 +180,7 @@ class RunCollection:
176
180
  Returns:
177
181
  The only `Run` instance in the collection, or None if the collection
178
182
  does not contain exactly one run.
183
+
179
184
  """
180
185
  return self._runs[0] if len(self._runs) == 1 else None
181
186
 
@@ -187,6 +192,7 @@ class RunCollection:
187
192
 
188
193
  Raises:
189
194
  ValueError: If the collection is empty.
195
+
190
196
  """
191
197
  if not self._runs:
192
198
  raise ValueError("The collection is empty.")
@@ -199,6 +205,7 @@ class RunCollection:
199
205
  Returns:
200
206
  The first `Run` instance in the collection, or None if the collection
201
207
  is empty.
208
+
202
209
  """
203
210
  return self._runs[0] if self._runs else None
204
211
 
@@ -210,6 +217,7 @@ class RunCollection:
210
217
 
211
218
  Raises:
212
219
  ValueError: If the collection is empty.
220
+
213
221
  """
214
222
  if not self._runs:
215
223
  raise ValueError("The collection is empty.")
@@ -222,6 +230,7 @@ class RunCollection:
222
230
  Returns:
223
231
  The last `Run` instance in the collection, or None if the collection
224
232
  is empty.
233
+
225
234
  """
226
235
  return self._runs[-1] if self._runs else None
227
236
 
@@ -262,6 +271,7 @@ class RunCollection:
262
271
 
263
272
  Returns:
264
273
  A new `RunCollection` object containing the filtered runs.
274
+
265
275
  """
266
276
  return RunCollection(
267
277
  filter_runs(
@@ -294,6 +304,7 @@ class RunCollection:
294
304
 
295
305
  See Also:
296
306
  `filter`: Perform the actual filtering logic.
307
+
297
308
  """
298
309
  try:
299
310
  return self.filter(config, **kwargs).first()
@@ -318,6 +329,7 @@ class RunCollection:
318
329
 
319
330
  See Also:
320
331
  `filter`: Perform the actual filtering logic.
332
+
321
333
  """
322
334
  return self.filter(config, **kwargs).try_first()
323
335
 
@@ -341,6 +353,7 @@ class RunCollection:
341
353
 
342
354
  See Also:
343
355
  `filter`: Perform the actual filtering logic.
356
+
344
357
  """
345
358
  try:
346
359
  return self.filter(config, **kwargs).last()
@@ -365,6 +378,7 @@ class RunCollection:
365
378
 
366
379
  See Also:
367
380
  `filter`: Perform the actual filtering logic.
381
+
368
382
  """
369
383
  return self.filter(config, **kwargs).try_last()
370
384
 
@@ -389,6 +403,7 @@ class RunCollection:
389
403
 
390
404
  See Also:
391
405
  `filter`: Perform the actual filtering logic.
406
+
392
407
  """
393
408
  try:
394
409
  return self.filter(config, **kwargs).one()
@@ -417,6 +432,7 @@ class RunCollection:
417
432
 
418
433
  See Also:
419
434
  `filter`: Perform the actual filtering logic.
435
+
420
436
  """
421
437
  return self.filter(config, **kwargs).try_one()
422
438
 
@@ -429,6 +445,7 @@ class RunCollection:
429
445
 
430
446
  Returns:
431
447
  A list of unique parameter names.
448
+
432
449
  """
433
450
  param_names = set()
434
451
 
@@ -453,6 +470,7 @@ class RunCollection:
453
470
  Returns:
454
471
  A dictionary where the keys are parameter names and the values are
455
472
  lists of parameter values.
473
+
456
474
  """
457
475
  params = {}
458
476
 
@@ -484,6 +502,7 @@ class RunCollection:
484
502
 
485
503
  Yields:
486
504
  Results obtained by applying the function to each run in the collection.
505
+
487
506
  """
488
507
  return (func(run, *args, **kwargs) for run in self)
489
508
 
@@ -504,6 +523,7 @@ class RunCollection:
504
523
  Yields:
505
524
  Results obtained by applying the function to each run id in the
506
525
  collection.
526
+
507
527
  """
508
528
  return (func(run_id, *args, **kwargs) for run_id in self.info.run_id)
509
529
 
@@ -524,6 +544,7 @@ class RunCollection:
524
544
  Yields:
525
545
  Results obtained by applying the function to each run configuration
526
546
  in the collection.
547
+
527
548
  """
528
549
  return (func(load_config(run), *args, **kwargs) for run in self)
529
550
 
@@ -548,6 +569,7 @@ class RunCollection:
548
569
  Yields:
549
570
  Results obtained by applying the function to each artifact URI in the
550
571
  collection.
572
+
551
573
  """
552
574
  return (func(uri, *args, **kwargs) for uri in self.info.artifact_uri)
553
575
 
@@ -571,6 +593,7 @@ class RunCollection:
571
593
  Yields:
572
594
  Results obtained by applying the function to each artifact directory
573
595
  in the collection.
596
+
574
597
  """
575
598
  return (func(dir, *args, **kwargs) for dir in self.info.artifact_dir) # noqa: A001
576
599
 
@@ -594,6 +617,7 @@ class RunCollection:
594
617
  dictionary where the keys are tuples of parameter values and the
595
618
  values are `RunCollection` objects containing the runs that match
596
619
  those parameter values.
620
+
597
621
  """
598
622
  grouped_runs: dict[str | None | tuple[str | None, ...], list[Run]] = {}
599
623
  is_list = isinstance(names, list)
@@ -620,6 +644,7 @@ class RunCollection:
620
644
  key (Callable[[Run], Any] | None): A function that takes a run and returns
621
645
  a value to sort by.
622
646
  reverse (bool): If True, sort in descending order.
647
+
623
648
  """
624
649
  self._runs.sort(key=key or (lambda x: x.info.start_time), reverse=reverse)
625
650
 
@@ -633,6 +658,7 @@ class RunCollection:
633
658
 
634
659
  Returns:
635
660
  A list of values for the specified parameters.
661
+
636
662
  """
637
663
  is_list = isinstance(names, list)
638
664
 
@@ -664,6 +690,7 @@ class RunCollection:
664
690
  This can be a single parameter name or multiple names provided
665
691
  as separate arguments or as a list.
666
692
  reverse (bool): If True, sort in descending order.
693
+
667
694
  """
668
695
  values = self.values(names)
669
696
  index = sorted(range(len(self)), key=lambda i: values[i], reverse=reverse)
@@ -721,6 +748,7 @@ def filter_runs(
721
748
 
722
749
  Returns:
723
750
  A list of runs that match the specified configuration and key-value pairs.
751
+
724
752
  """
725
753
  if override:
726
754
  config = select_overrides(config)
@@ -751,6 +779,7 @@ def filter_runs_by_status(
751
779
 
752
780
  Returns:
753
781
  A list of runs that match the specified status.
782
+
754
783
  """
755
784
  if isinstance(status, str):
756
785
  if status.startswith("!"):
hydraflow/run_data.py CHANGED
@@ -37,6 +37,7 @@ class RunCollectionData:
37
37
 
38
38
  Returns:
39
39
  A DataFrame containing the runs' configurations.
40
+
40
41
  """
41
42
  return DataFrame(self._runs.map_config(collect_params))
42
43
 
hydraflow/utils.py CHANGED
@@ -3,6 +3,8 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import shutil
6
+ import urllib.parse
7
+ import urllib.request
6
8
  from pathlib import Path
7
9
  from typing import TYPE_CHECKING
8
10
 
@@ -16,29 +18,40 @@ if TYPE_CHECKING:
16
18
  from collections.abc import Iterable
17
19
 
18
20
 
19
- def get_artifact_dir(run: Run | None = None) -> Path:
21
+ def get_artifact_dir(run: Run | None = None, uri: str | None = None) -> Path:
20
22
  """Retrieve the artifact directory for the given run.
21
23
 
22
24
  This function uses MLflow to get the artifact directory for the given run.
23
25
 
24
26
  Args:
25
27
  run (Run | None): The run object. Defaults to None.
28
+ uri (str | None): The URI of the artifact. Defaults to None.
26
29
 
27
30
  Returns:
28
31
  The local path to the directory where the artifacts are downloaded.
32
+
29
33
  """
30
- uri = mlflow.get_artifact_uri() if run is None else run.info.artifact_uri
34
+ if run is not None and uri is not None:
35
+ raise ValueError("Cannot provide both run and uri")
36
+
37
+ if run is None and uri is None:
38
+ uri = mlflow.get_artifact_uri()
39
+ elif run:
40
+ uri = run.info.artifact_uri
31
41
 
32
42
  if not isinstance(uri, str):
33
43
  raise NotImplementedError
34
44
 
35
45
  if uri.startswith("file:"):
36
- return Path(mlflow.artifacts.download_artifacts(uri))
46
+ return file_uri_to_path(uri)
37
47
 
38
- if Path(uri).is_dir():
39
- return Path(uri)
48
+ return Path(uri)
40
49
 
41
- raise NotImplementedError
50
+
51
+ def file_uri_to_path(uri: str) -> Path:
52
+ """Convert a file URI to a local path."""
53
+ path = urllib.parse.urlparse(uri).path
54
+ return Path(urllib.request.url2pathname(path)) # for Windows
42
55
 
43
56
 
44
57
  def get_artifact_path(run: Run | None, path: str) -> Path:
@@ -52,6 +65,7 @@ def get_artifact_path(run: Run | None, path: str) -> Path:
52
65
 
53
66
  Returns:
54
67
  The local path to the artifact.
68
+
55
69
  """
56
70
  return get_artifact_dir(run) / path
57
71
 
@@ -74,6 +88,7 @@ def get_hydra_output_dir(run: Run | None = None) -> Path:
74
88
  Raises:
75
89
  FileNotFoundError: If the Hydra configuration file is not found
76
90
  in the artifacts.
91
+
77
92
  """
78
93
  if run is None:
79
94
  hc = HydraConfig.get()
@@ -102,6 +117,7 @@ def load_config(run: Run) -> DictConfig:
102
117
  Returns:
103
118
  The loaded configuration as a DictConfig object. Returns an empty
104
119
  DictConfig if the configuration file is not found.
120
+
105
121
  """
106
122
  path = get_artifact_dir(run) / ".hydra/config.yaml"
107
123
  return OmegaConf.load(path) # type: ignore
@@ -126,6 +142,7 @@ def load_overrides(run: Run) -> list[str]:
126
142
  Returns:
127
143
  The loaded overrides as a list of strings. Returns an empty list
128
144
  if the overrides file is not found.
145
+
129
146
  """
130
147
  path = get_artifact_dir(run) / ".hydra/overrides.yaml"
131
148
  return [str(x) for x in OmegaConf.load(path)]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hydraflow
3
- Version: 0.5.4
3
+ Version: 0.6.1
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
@@ -0,0 +1,14 @@
1
+ hydraflow/__init__.py,sha256=VPIPNNCyjMAkWBbdvB7Ltwe3QWoc2FwuqkV8uJM5JoM,809
2
+ hydraflow/config.py,sha256=MNX9da5bPVDcjnpji7Cm9ndK6ura92pt361m4PRh6_E,4326
3
+ hydraflow/context.py,sha256=3xfKhMozkKFqtWeOp9Gie0A5o5URMta4US6iVD5TcLU,6002
4
+ hydraflow/mlflow.py,sha256=imD3XL0RTlpnKrkyvO8FNy_Bv6hwSfLiOu1yJuL40ck,8773
5
+ hydraflow/param.py,sha256=yu1aMNXRLegXGDL-68vwIkfeDF9CaU784WZENGLwl7Q,4572
6
+ hydraflow/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ hydraflow/run_collection.py,sha256=2GRVOy87_2SPjHuCzzUvRNugO_grtFUVjtTfhznwBAc,27444
8
+ hydraflow/run_data.py,sha256=dpyyfnuH9mCtIZeigMo1iFQo9bafMdEL4i4uI2l0UqY,1525
9
+ hydraflow/run_info.py,sha256=Jf5wrIjRLIV1-k-obHDqwKHa6j_ZonrY8od-rXlbtMo,1024
10
+ hydraflow/utils.py,sha256=a9i5PEJn8Ssowv9dqHadAihZXlsqtVjHZ9MZvkPq1bY,4747
11
+ hydraflow-0.6.1.dist-info/METADATA,sha256=FzLPE3L9VlZdrYOicnzTda7BhHuLTU0-WRz02TLgt6c,4700
12
+ hydraflow-0.6.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
13
+ hydraflow-0.6.1.dist-info/licenses/LICENSE,sha256=IGdDrBPqz1O0v_UwCW-NJlbX9Hy9b3uJ11t28y2srmY,1062
14
+ hydraflow-0.6.1.dist-info/RECORD,,
@@ -1,14 +0,0 @@
1
- hydraflow/__init__.py,sha256=9XO9FD3uiTTPN6X6UAC9FtkJjEqUQZNqpoAmSrjUHfI,855
2
- hydraflow/config.py,sha256=k6pwneDoC4mb7cVkafMfITn8QemICPnFbhIRGLsmF4w,4323
3
- hydraflow/context.py,sha256=KukvVexCF32myBOryYMVhINknbAgPFcanmr4cT2EXog,5521
4
- hydraflow/mlflow.py,sha256=TVp6O9rYNYcdqnlssstXQlI_P_N6inUG-F01X6uJNv4,8928
5
- hydraflow/param.py,sha256=kuVlxEfgoKL35rNu49M-PkdNr41djK0YZ5IO7fHTSSU,4568
6
- hydraflow/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- hydraflow/run_collection.py,sha256=mMGpr6cAh9Bf2SeRsYNHySOQJNrWNMI7esDWzyMxnJg,27415
8
- hydraflow/run_data.py,sha256=V_yhkBsJlDTkLbh1TShkvDxUQYUYTpXFahXJGfdmgro,1524
9
- hydraflow/run_info.py,sha256=Jf5wrIjRLIV1-k-obHDqwKHa6j_ZonrY8od-rXlbtMo,1024
10
- hydraflow/utils.py,sha256=ha-gSq3TkWWOlKmnDuyLNCuKNQdEG08CXRzKtb3C4mk,4344
11
- hydraflow-0.5.4.dist-info/METADATA,sha256=ijJv5powqpMjZ1adDCWdLxRLeEaosmKF3gG74L25fCs,4700
12
- hydraflow-0.5.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
13
- hydraflow-0.5.4.dist-info/licenses/LICENSE,sha256=IGdDrBPqz1O0v_UwCW-NJlbX9Hy9b3uJ11t28y2srmY,1062
14
- hydraflow-0.5.4.dist-info/RECORD,,