hydraflow 0.2.1__py3-none-any.whl → 0.2.2__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
hydraflow/__init__.py CHANGED
@@ -2,18 +2,19 @@ from .context import Info, chdir_artifact, log_run, watch
2
2
  from .mlflow import set_experiment
3
3
  from .runs import (
4
4
  Run,
5
- Runs,
5
+ RunCollection,
6
6
  filter_runs,
7
7
  get_param_dict,
8
8
  get_param_names,
9
9
  get_run,
10
10
  load_config,
11
+ search_runs,
11
12
  )
12
13
 
13
14
  __all__ = [
14
15
  "Info",
15
16
  "Run",
16
- "Runs",
17
+ "RunCollection",
17
18
  "chdir_artifact",
18
19
  "filter_runs",
19
20
  "get_param_dict",
@@ -21,6 +22,7 @@ __all__ = [
21
22
  "get_run",
22
23
  "load_config",
23
24
  "log_run",
25
+ "search_runs",
24
26
  "set_experiment",
25
27
  "watch",
26
28
  ]
hydraflow/config.py CHANGED
@@ -30,6 +30,9 @@ def iter_params(config: object, prefix: str = "") -> Iterator[tuple[str, Any]]:
30
30
  Yields:
31
31
  Key-value pairs representing the parameters in the configuration object.
32
32
  """
33
+ if config is None:
34
+ return
35
+
33
36
  if not isinstance(config, (DictConfig, ListConfig)):
34
37
  config = OmegaConf.create(config) # type: ignore
35
38
 
hydraflow/runs.py CHANGED
@@ -1,7 +1,7 @@
1
1
  """
2
2
  This module provides functionality for managing and interacting with MLflow runs.
3
- It includes the `Runs` class and various methods to filter runs, retrieve run information,
4
- log artifacts, and load configurations.
3
+ It includes the `RunCollection` class and various methods to filter runs,
4
+ retrieve run information, log artifacts, and load configurations.
5
5
  """
6
6
 
7
7
  from __future__ import annotations
@@ -9,9 +9,10 @@ from __future__ import annotations
9
9
  from dataclasses import dataclass
10
10
  from functools import cache
11
11
  from itertools import chain
12
- from typing import TYPE_CHECKING, Any
12
+ from typing import TYPE_CHECKING, Any, TypeVar
13
13
 
14
14
  import mlflow
15
+ from mlflow.artifacts import download_artifacts
15
16
  from mlflow.entities import ViewType
16
17
  from mlflow.entities.run import Run
17
18
  from mlflow.tracking.fluent import SEARCH_MAX_RESULTS_PANDAS
@@ -20,6 +21,7 @@ from omegaconf import DictConfig, OmegaConf
20
21
  from hydraflow.config import iter_params
21
22
 
22
23
  if TYPE_CHECKING:
24
+ from collections.abc import Callable, Iterator
23
25
  from typing import Any
24
26
 
25
27
 
@@ -31,14 +33,17 @@ def search_runs(
31
33
  order_by: list[str] | None = None,
32
34
  search_all_experiments: bool = False,
33
35
  experiment_names: list[str] | None = None,
34
- ) -> Runs:
36
+ ) -> RunCollection:
35
37
  """
36
38
  Search for Runs that fit the specified criteria.
37
39
 
38
40
  This function wraps the `mlflow.search_runs` function and returns the results
39
- as a `Runs` object. It allows for flexible searching of MLflow runs based on
41
+ as a `RunCollection` object. It allows for flexible searching of MLflow runs based on
40
42
  various criteria.
41
43
 
44
+ Note:
45
+ The returned runs are sorted by their start time in ascending order.
46
+
42
47
  Args:
43
48
  experiment_ids: List of experiment IDs. Search can work with experiment IDs or
44
49
  experiment names, but not both in the same call. Values other than
@@ -53,9 +58,6 @@ def search_runs(
53
58
  order_by: List of columns to order by (e.g., "metrics.rmse"). The ``order_by`` column
54
59
  can contain an optional ``DESC`` or ``ASC`` value. The default is ``ASC``.
55
60
  The default ordering is to sort by ``start_time DESC``, then ``run_id``.
56
- output_format: The output format to be returned. If ``pandas``, a ``pandas.DataFrame``
57
- is returned and, if ``list``, a list of :py:class:`mlflow.entities.Run`
58
- is returned.
59
61
  search_all_experiments: Boolean specifying whether all experiments should be searched.
60
62
  Only honored if ``experiment_ids`` is ``[]`` or ``None``.
61
63
  experiment_names: List of experiment names. Search can work with experiment IDs or
@@ -65,7 +67,7 @@ def search_runs(
65
67
  experiment if ``experiment_ids`` is ``None`` or ``[]``.
66
68
 
67
69
  Returns:
68
- A `Runs` object containing the search results.
70
+ A `RunCollection` object containing the search results.
69
71
  """
70
72
  runs = mlflow.search_runs(
71
73
  experiment_ids=experiment_ids,
@@ -77,11 +79,44 @@ def search_runs(
77
79
  search_all_experiments=search_all_experiments,
78
80
  experiment_names=experiment_names,
79
81
  )
80
- return Runs(runs) # type: ignore
82
+ runs = sorted(runs, key=lambda run: run.info.start_time) # type: ignore
83
+ return RunCollection(runs) # type: ignore
84
+
85
+
86
+ def list_runs(experiment_names: list[str] | None = None) -> RunCollection:
87
+ """
88
+ List all runs for the specified experiments.
89
+
90
+ This function retrieves all runs for the given list of experiment names.
91
+ If no experiment names are provided (None), it defaults to searching all runs
92
+ for the currently active experiment. If an empty list is provided, the function
93
+ will search all runs for all experiments except the "Default" experiment.
94
+ The function returns the results as a `RunCollection` object.
95
+
96
+ Note:
97
+ The returned runs are sorted by their start time in ascending order.
98
+
99
+ Args:
100
+ experiment_names: List of experiment names to search for runs.
101
+ If None or an empty list is provided, the function will search
102
+ the currently active experiment or all experiments except the
103
+ "Default" experiment.
104
+
105
+ Returns:
106
+ A `RunCollection` object containing the runs for the specified experiments.
107
+ """
108
+ if experiment_names == []:
109
+ experiments = mlflow.search_experiments()
110
+ experiment_names = [e.name for e in experiments if e.name != "Default"]
111
+
112
+ return search_runs(experiment_names=experiment_names)
113
+
114
+
115
+ T = TypeVar("T")
81
116
 
82
117
 
83
118
  @dataclass
84
- class Runs:
119
+ class RunCollection:
85
120
  """
86
121
  A class to represent a collection of MLflow runs.
87
122
 
@@ -89,83 +124,109 @@ class Runs:
89
124
  retrieving specific runs, and accessing run information.
90
125
  """
91
126
 
92
- runs: list[Run]
127
+ _runs: list[Run]
128
+ """A list of MLflow Run objects."""
93
129
 
94
130
  def __repr__(self) -> str:
95
131
  return f"{self.__class__.__name__}({len(self)})"
96
132
 
97
133
  def __len__(self) -> int:
98
- return len(self.runs)
134
+ return len(self._runs)
99
135
 
100
- def filter(self, config: object) -> Runs:
136
+ def filter(self, config: object | None = None, **kwargs) -> RunCollection:
101
137
  """
102
138
  Filter the runs based on the provided configuration.
103
139
 
104
140
  This method filters the runs in the collection according to the
105
- specified configuration object. The configuration object should
106
- contain key-value pairs that correspond to the parameters of the
107
- runs. Only the runs that match all the specified parameters will
108
- be included in the returned `Runs` object.
141
+ specified configuration object and additional key-value pairs.
142
+ The configuration object and key-value pairs should contain
143
+ key-value pairs that correspond to the parameters of the runs.
144
+ Only the runs that match all the specified parameters will be
145
+ included in the returned `RunCollection` object.
146
+
147
+ The filtering supports:
148
+ - Exact matches for single values.
149
+ - Membership checks for lists of values.
150
+ - Range checks for tuples of two values (inclusive of the lower bound and
151
+ exclusive of the upper bound).
109
152
 
110
153
  Args:
111
- config: The configuration object to filter the runs.
154
+ config: The configuration object to filter the runs. This can be any
155
+ object that provides key-value pairs through the `iter_params`
156
+ function.
157
+ **kwargs: Additional key-value pairs to filter the runs.
112
158
 
113
159
  Returns:
114
- A new `Runs` object containing the filtered runs.
160
+ A new `RunCollection` object containing the filtered runs.
115
161
  """
116
- return Runs(filter_runs(self.runs, config))
162
+ return RunCollection(filter_runs(self._runs, config, **kwargs))
117
163
 
118
- def get(self, config: object) -> Run | None:
164
+ def find(self, config: object | None = None, **kwargs) -> Run | None:
119
165
  """
120
- Retrieve a specific run based on the provided configuration.
166
+ Find the first run based on the provided configuration.
121
167
 
122
168
  This method filters the runs in the collection according to the
123
- specified configuration object and returns the run that matches
124
- the provided parameters. If more than one run matches the criteria,
125
- a `ValueError` is raised.
169
+ specified configuration object and returns the first run that matches
170
+ the provided parameters. If no run matches the criteria, None is returned.
126
171
 
127
172
  Args:
128
173
  config: The configuration object to identify the run.
174
+ **kwargs: Additional key-value pairs to filter the runs.
129
175
 
130
176
  Returns:
131
- Run: The run object that matches the provided configuration.
132
- None, if the runs are not in a DataFrame format.
177
+ The first run object that matches the provided configuration, or None
178
+ if no runs match the criteria.
133
179
 
134
- Raises:
135
- ValueError: If the number of filtered runs is not exactly one.
180
+ See Also:
181
+ RunCollection.filter: The method that performs the actual filtering logic.
136
182
  """
137
- return get_run(self.runs, config)
183
+ return find_run(self._runs, config, **kwargs)
138
184
 
139
- def get_earliest_run(self, config: object | None = None, **kwargs) -> Run | None:
185
+ def find_last(self, config: object | None = None, **kwargs) -> Run | None:
140
186
  """
141
- Get the earliest run from the list of runs based on the start time.
187
+ Find the last run based on the provided configuration.
142
188
 
143
- This method filters the runs based on the configuration if provided
144
- and returns the run with the earliest start time.
189
+ This method filters the runs in the collection according to the
190
+ specified configuration object and returns the last run that matches
191
+ the provided parameters. If no run matches the criteria, None is returned.
145
192
 
146
193
  Args:
147
- config: The configuration object to filter the runs.
148
- If None, no filtering is applied.
194
+ config: The configuration object to identify the run.
149
195
  **kwargs: Additional key-value pairs to filter the runs.
150
196
 
151
197
  Returns:
152
- The run with the earliest start time, or None if no runs match the criteria.
198
+ The last run object that matches the provided configuration, or None
199
+ if no runs match the criteria.
200
+
201
+ See Also:
202
+ RunCollection.filter: The method that performs the actual filtering logic.
153
203
  """
154
- return get_earliest_run(self.runs, config, **kwargs)
204
+ return find_last_run(self._runs, config, **kwargs)
155
205
 
156
- def get_latest_run(self, config: object | None = None, **kwargs) -> Run | None:
206
+ def get(self, config: object | None = None, **kwargs) -> Run | None:
157
207
  """
158
- Get the latest run from the list of runs based on the start time.
208
+ Retrieve a specific run based on the provided configuration.
209
+
210
+ This method filters the runs in the collection according to the
211
+ specified configuration object and returns the run that matches
212
+ the provided parameters. If more than one run matches the criteria,
213
+ a `ValueError` is raised.
159
214
 
160
215
  Args:
161
- config: The configuration object to filter the runs.
162
- If None, no filtering is applied.
216
+ config: The configuration object to identify the run.
163
217
  **kwargs: Additional key-value pairs to filter the runs.
164
218
 
165
219
  Returns:
166
- The run with the latest start time, or None if no runs match the criteria.
220
+ The run object that matches the provided configuration, or None
221
+ if no runs match the criteria.
222
+
223
+ Raises:
224
+ ValueError: If more than one run matches the criteria.
225
+
226
+ See Also:
227
+ RunCollection.filter: The method that performs the actual filtering logic.
167
228
  """
168
- return get_latest_run(self.runs, config, **kwargs)
229
+ return get_run(self._runs, config, **kwargs)
169
230
 
170
231
  def get_param_names(self) -> list[str]:
171
232
  """
@@ -178,7 +239,7 @@ class Runs:
178
239
  Returns:
179
240
  A list of unique parameter names.
180
241
  """
181
- return get_param_names(self.runs)
242
+ return get_param_names(self._runs)
182
243
 
183
244
  def get_param_dict(self) -> dict[str, list[str]]:
184
245
  """
@@ -193,29 +254,164 @@ class Runs:
193
254
  A dictionary where the keys are parameter names and the values are lists
194
255
  of parameter values.
195
256
  """
196
- return get_param_dict(self.runs)
257
+ return get_param_dict(self._runs)
258
+
259
+ def first(self) -> Run | None:
260
+ """
261
+ Return the first run in the collection.
262
+
263
+ Returns:
264
+ The first Run object if the collection is not empty, otherwise None.
265
+ """
266
+ return self._runs[0] if self._runs else None
267
+
268
+ def last(self) -> Run | None:
269
+ """
270
+ Return the last run in the collection.
271
+
272
+ Returns:
273
+ The last Run object if the collection is not empty, otherwise None.
274
+ """
275
+ return self._runs[-1] if self._runs else None
276
+
277
+ def map(self, func: Callable[[Run], T]) -> Iterator[T]:
278
+ """
279
+ Apply a function to each run in the collection and return an iterator of results.
280
+
281
+ Args:
282
+ func: A function that takes a Run object and returns a result.
283
+
284
+ Returns:
285
+ An iterator of results obtained by applying the function to each run
286
+ in the collection.
287
+ """
288
+ return (func(run) for run in self._runs)
289
+
290
+ def map_run_id(self, func: Callable[[str], T]) -> Iterator[T]:
291
+ """
292
+ Apply a function to each run id in the collection and return an iterator of results.
293
+
294
+ Args:
295
+ func: A function that takes a run id and returns a result.
296
+
297
+ Returns:
298
+ An iterator of results obtained by applying the function to each run id
299
+ in the collection.
300
+ """
301
+ return (func(run.info.run_id) for run in self._runs)
302
+
303
+ def map_config(self, func: Callable[[DictConfig], T]) -> Iterator[T]:
304
+ """
305
+ Apply a function to each run config in the collection and return an iterator of results.
306
+
307
+ Args:
308
+ func: A function that takes a run config and returns a result.
309
+
310
+ Returns:
311
+ An iterator of results obtained by applying the function to each run config
312
+ in the collection.
313
+ """
314
+ return (func(load_config(run)) for run in self._runs)
315
+
316
+ def map_uri(self, func: Callable[[str | None], T]) -> Iterator[T]:
317
+ """
318
+ Apply a function to each artifact URI in the collection and return an iterator of results.
319
+
320
+ This method iterates over each run in the collection, retrieves the artifact URI,
321
+ and applies the provided function to it. If a run does not have an artifact URI,
322
+ None is passed to the function.
323
+
324
+ Args:
325
+ func: A function that takes an artifact URI (string or None) and returns a result.
326
+
327
+ Yields:
328
+ The results obtained by applying the function to each artifact URI in the collection.
329
+ """
330
+ return (func(run.info.artifact_uri) for run in self._runs)
331
+
332
+ def map_dir(self, func: Callable[[str], T]) -> Iterator[T]:
333
+ """
334
+ Apply a function to each artifact directory in the collection and return an iterator of results.
335
+
336
+ This method iterates over each run in the collection, downloads the artifact directory,
337
+ and applies the provided function to the directory path.
338
+
339
+ Args:
340
+ func: A function that takes an artifact directory path (string) and returns a result.
341
+
342
+ Returns:
343
+ An iterator of results obtained by applying the function to each artifact directory
344
+ in the collection.
345
+ """
346
+ return (func(download_artifacts(run_id=run.info.run_id)) for run in self._runs)
347
+
348
+
349
+ def _param_matches(run: Run, key: str, value: Any) -> bool:
350
+ """
351
+ Check if the run's parameter matches the specified key-value pair.
352
+
353
+ This function checks if the run's parameters contain the specified key-value pair.
354
+ It handles different types of values, including lists and tuples.
355
+
356
+ Args:
357
+ run: The run object to check.
358
+ key: The parameter key to check.
359
+ value: The parameter value to check.
360
+
361
+ Returns:
362
+ True if the run's parameter matches the specified key-value pair, False otherwise.
363
+ """
364
+ param = run.data.params.get(key, value)
365
+
366
+ # FIXME: This is a workaround to handle the case where the parameter value is a list
367
+ # We need to improve the logic to handle different types of values
368
+ # For now, we assume that if the parameter is a list, we should check if it contains the value
369
+ # This is not ideal, but it works for the case where the parameter value is a list of strings
370
+ # We should improve the logic to handle different types of values in the future
371
+
372
+ if param is None:
373
+ return False
374
+
375
+ if param == "None":
376
+ return value is None
197
377
 
378
+ if isinstance(value, list) and value:
379
+ return type(value[0])(param) in value
198
380
 
199
- def filter_runs(runs: list[Run], config: object, **kwargs) -> list[Run]:
381
+ if isinstance(value, tuple) and len(value) == 2:
382
+ return value[0] <= type(value[0])(param) < value[1]
383
+
384
+ return type(value)(param) == value
385
+
386
+
387
+ def filter_runs(runs: list[Run], config: object | None = None, **kwargs) -> list[Run]:
200
388
  """
201
389
  Filter the runs based on the provided configuration.
202
390
 
203
391
  This method filters the runs in the collection according to the
204
- specified configuration object. The configuration object should
205
- contain key-value pairs that correspond to the parameters of the
206
- runs. Only the runs that match all the specified parameters will
207
- be included in the returned list of runs.
392
+ specified configuration object and additional key-value pairs.
393
+ The configuration object and key-value pairs should contain
394
+ key-value pairs that correspond to the parameters of the runs.
395
+ Only the runs that match all the specified parameters will be
396
+ included in the returned list of runs.
397
+
398
+ The filtering supports:
399
+ - Exact matches for single values.
400
+ - Membership checks for lists of values.
401
+ - Range checks for tuples of two values (inclusive of the lower bound and
402
+ exclusive of the upper bound).
208
403
 
209
404
  Args:
210
- runs: The runs to filter.
211
- config: The configuration object to filter the runs.
405
+ runs: The list of runs to filter.
406
+ config: The configuration object to filter the runs. This can be any object that
407
+ provides key-value pairs through the `iter_params` function.
212
408
  **kwargs: Additional key-value pairs to filter the runs.
213
409
 
214
410
  Returns:
215
- A filtered list of runs.
411
+ A list of runs that match the specified configuration and key-value pairs.
216
412
  """
217
413
  for key, value in chain(iter_params(config), kwargs.items()):
218
- runs = [run for run in runs if _is_equal(run, key, value)]
414
+ runs = [run for run in runs if _param_matches(run, key, value)]
219
415
 
220
416
  if len(runs) == 0:
221
417
  return []
@@ -223,23 +419,13 @@ def filter_runs(runs: list[Run], config: object, **kwargs) -> list[Run]:
223
419
  return runs
224
420
 
225
421
 
226
- def _is_equal(run: Run, key: str, value: Any) -> bool:
227
- param = run.data.params.get(key, value)
228
-
229
- if param is None:
230
- return False
231
-
232
- return type(value)(param) == value
233
-
234
-
235
- def get_run(runs: list[Run], config: object, **kwargs) -> Run | None:
422
+ def find_run(runs: list[Run], config: object | None = None, **kwargs) -> Run | None:
236
423
  """
237
- Retrieve a specific run based on the provided configuration.
424
+ Find the first run based on the provided configuration.
238
425
 
239
426
  This method filters the runs in the collection according to the
240
- specified configuration object and returns the run that matches
241
- the provided parameters. If more than one run matches the criteria,
242
- a `ValueError` is raised.
427
+ specified configuration object and returns the first run that matches
428
+ the provided parameters. If no run matches the criteria, None is returned.
243
429
 
244
430
  Args:
245
431
  runs: The runs to filter.
@@ -247,66 +433,65 @@ def get_run(runs: list[Run], config: object, **kwargs) -> Run | None:
247
433
  **kwargs: Additional key-value pairs to filter the runs.
248
434
 
249
435
  Returns:
250
- The run object that matches the provided configuration, or None
436
+ The first run object that matches the provided configuration, or None
251
437
  if no runs match the criteria.
252
-
253
- Raises:
254
- ValueError: If more than one run matches the criteria.
255
438
  """
256
439
  runs = filter_runs(runs, config, **kwargs)
440
+ return runs[0] if runs else None
257
441
 
258
- if len(runs) == 0:
259
- return None
260
-
261
- if len(runs) == 1:
262
- return runs[0]
263
-
264
- msg = f"Multiple runs were filtered. Expected number of runs is 1, but found {len(runs)} runs."
265
- raise ValueError(msg)
266
442
 
267
-
268
- def get_earliest_run(runs: list[Run], config: object | None = None, **kwargs) -> Run | None:
443
+ def find_last_run(runs: list[Run], config: object | None = None, **kwargs) -> Run | None:
269
444
  """
270
- Get the earliest run from the list of runs based on the start time.
445
+ Find the last run based on the provided configuration.
271
446
 
272
- This method filters the runs based on the configuration if provided
273
- and returns the run with the earliest start time.
447
+ This method filters the runs in the collection according to the
448
+ specified configuration object and returns the last run that matches
449
+ the provided parameters. If no run matches the criteria, None is returned.
274
450
 
275
451
  Args:
276
- runs: The list of runs.
277
- config: The configuration object to filter the runs.
278
- If None, no filtering is applied.
452
+ runs: The runs to filter.
453
+ config: The configuration object to identify the run.
279
454
  **kwargs: Additional key-value pairs to filter the runs.
280
455
 
281
456
  Returns:
282
- The run with the earliest start time, or None if no runs match the criteria.
457
+ The last run object that matches the provided configuration, or None
458
+ if no runs match the criteria.
283
459
  """
284
- if config is not None or kwargs:
285
- runs = filter_runs(runs, config or {}, **kwargs)
286
-
287
- return min(runs, key=lambda run: run.info.start_time, default=None)
460
+ runs = filter_runs(runs, config, **kwargs)
461
+ return runs[-1] if runs else None
288
462
 
289
463
 
290
- def get_latest_run(runs: list[Run], config: object | None = None, **kwargs) -> Run | None:
464
+ def get_run(runs: list[Run], config: object | None = None, **kwargs) -> Run | None:
291
465
  """
292
- Get the latest run from the list of runs based on the start time.
466
+ Retrieve a specific run based on the provided configuration.
293
467
 
294
- This method filters the runs based on the configuration if provided
295
- and returns the run with the latest start time.
468
+ This method filters the runs in the collection according to the
469
+ specified configuration object and returns the run that matches
470
+ the provided parameters. If more than one run matches the criteria,
471
+ a `ValueError` is raised.
296
472
 
297
473
  Args:
298
- runs: The list of runs.
299
- config: The configuration object to filter the runs.
300
- If None, no filtering is applied.
474
+ runs: The runs to filter.
475
+ config: The configuration object to identify the run.
301
476
  **kwargs: Additional key-value pairs to filter the runs.
302
477
 
303
478
  Returns:
304
- The run with the latest start time, or None if no runs match the criteria.
479
+ The run object that matches the provided configuration, or None
480
+ if no runs match the criteria.
481
+
482
+ Raises:
483
+ ValueError: If more than one run matches the criteria.
305
484
  """
306
- if config is not None or kwargs:
307
- runs = filter_runs(runs, config or {}, **kwargs)
485
+ runs = filter_runs(runs, config, **kwargs)
308
486
 
309
- return max(runs, key=lambda run: run.info.start_time, default=None)
487
+ if len(runs) == 0:
488
+ return None
489
+
490
+ if len(runs) == 1:
491
+ return runs[0]
492
+
493
+ msg = f"Multiple runs were filtered. Expected number of runs is 1, but found {len(runs)} runs."
494
+ raise ValueError(msg)
310
495
 
311
496
 
312
497
  def get_param_names(runs: list[Run]) -> list[str]:
@@ -363,13 +548,15 @@ def load_config(run: Run) -> DictConfig:
363
548
 
364
549
  This function loads the configuration for the provided Run instance
365
550
  by downloading the configuration file from the MLflow artifacts and
366
- loading it using OmegaConf.
551
+ loading it using OmegaConf. It returns an empty config if
552
+ `.hydra/config.yaml` is not found in the run's artifact directory.
367
553
 
368
554
  Args:
369
- run: The Run instance to load the configuration for.
555
+ run: The Run instance for which to load the configuration.
370
556
 
371
557
  Returns:
372
- The loaded configuration.
558
+ The loaded configuration as a DictConfig object. Returns an empty
559
+ DictConfig if the configuration file is not found.
373
560
  """
374
561
  run_id = run.info.run_id
375
562
  return _load_config(run_id)
@@ -378,10 +565,7 @@ def load_config(run: Run) -> DictConfig:
378
565
  @cache
379
566
  def _load_config(run_id: str) -> DictConfig:
380
567
  try:
381
- path = mlflow.artifacts.download_artifacts(
382
- run_id=run_id,
383
- artifact_path=".hydra/config.yaml",
384
- )
568
+ path = download_artifacts(run_id=run_id, artifact_path=".hydra/config.yaml")
385
569
  except OSError:
386
570
  return DictConfig({})
387
571
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: hydraflow
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: Hydraflow integrates Hydra and MLflow to manage and track machine learning experiments.
5
5
  Project-URL: Documentation, https://github.com/daizutabi/hydraflow
6
6
  Project-URL: Source, https://github.com/daizutabi/hydraflow
@@ -46,14 +46,23 @@ Description-Content-Type: text/markdown
46
46
 
47
47
  ## Overview
48
48
 
49
- Hydraflow is a powerful library designed to seamlessly integrate [Hydra](https://hydra.cc/) and [MLflow](https://mlflow.org/), making it easier to manage and track machine learning experiments. By combining the flexibility of Hydra's configuration management with the robust experiment tracking capabilities of MLflow, Hydraflow provides a comprehensive solution for managing complex machine learning workflows.
49
+ Hydraflow is a powerful library designed to seamlessly integrate
50
+ [Hydra](https://hydra.cc/) and [MLflow](https://mlflow.org/), making it easier to
51
+ manage and track machine learning experiments. By combining the flexibility of
52
+ Hydra's configuration management with the robust experiment tracking capabilities
53
+ of MLflow, Hydraflow provides a comprehensive solution for managing complex
54
+ machine learning workflows.
50
55
 
51
56
  ## Key Features
52
57
 
53
- - **Configuration Management**: Utilize Hydra's advanced configuration management to handle complex parameter sweeps and experiment setups.
54
- - **Experiment Tracking**: Leverage MLflow's tracking capabilities to log parameters, metrics, and artifacts for each run.
55
- - **Artifact Management**: Automatically log and manage artifacts, such as model checkpoints and configuration files, with MLflow.
56
- - **Seamless Integration**: Easily integrate Hydra and MLflow in your machine learning projects with minimal setup.
58
+ - **Configuration Management**: Utilize Hydra's advanced configuration management
59
+ to handle complex parameter sweeps and experiment setups.
60
+ - **Experiment Tracking**: Leverage MLflow's tracking capabilities to log parameters,
61
+ metrics, and artifacts for each run.
62
+ - **Artifact Management**: Automatically log and manage artifacts, such as model
63
+ checkpoints and configuration files, with MLflow.
64
+ - **Seamless Integration**: Easily integrate Hydra and MLflow in your machine learning
65
+ projects with minimal setup.
57
66
 
58
67
  ## Installation
59
68
 
@@ -0,0 +1,9 @@
1
+ hydraflow/__init__.py,sha256=ht4I3q_Ronw2jzk_QRsV-IzObR31F_4Wy7Ve0syNm-8,496
2
+ hydraflow/config.py,sha256=FNTuCppjCMrZKVByJMrWKbgj3HeMWWwAmQNoyFe029Y,2087
3
+ hydraflow/context.py,sha256=MqkEhKEZL_N3eb3v5u9D4EqKkiSmiPyXXafhPkALRlg,5129
4
+ hydraflow/mlflow.py,sha256=_Los9E38eG8sTiN8bGwZmvjCrS0S-wSGiA4fyhQM3Zw,2251
5
+ hydraflow/runs.py,sha256=kO7Gl9CeS2HjB0y_emGXNMRJTxNoqXBEJ7Ggq96nhMg,22050
6
+ hydraflow-0.2.2.dist-info/METADATA,sha256=C2lfD6jTDdHyexxATZWfdRQHAUgSOHx7IgvmBUj4tTQ,4232
7
+ hydraflow-0.2.2.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
8
+ hydraflow-0.2.2.dist-info/licenses/LICENSE,sha256=IGdDrBPqz1O0v_UwCW-NJlbX9Hy9b3uJ11t28y2srmY,1062
9
+ hydraflow-0.2.2.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- hydraflow/__init__.py,sha256=PzziOG9RnGAVbl9Yz4ScvsL8nfkjsuN0alMKRvZT-_Y,442
2
- hydraflow/config.py,sha256=wI8uNuD2D-hIf4BAhEYJaMC6EyO-erKopy_ia_b1pYA,2048
3
- hydraflow/context.py,sha256=MqkEhKEZL_N3eb3v5u9D4EqKkiSmiPyXXafhPkALRlg,5129
4
- hydraflow/mlflow.py,sha256=_Los9E38eG8sTiN8bGwZmvjCrS0S-wSGiA4fyhQM3Zw,2251
5
- hydraflow/runs.py,sha256=NT7IzE-Pf7T2Ey-eWEPZzQQaX4Gt_RKDKSn2pj2yzGc,14304
6
- hydraflow-0.2.1.dist-info/METADATA,sha256=4C_hnw1gMb8WUQXyqj4q8eA1IVbp0wZuLGGthIk1G7U,4224
7
- hydraflow-0.2.1.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
8
- hydraflow-0.2.1.dist-info/licenses/LICENSE,sha256=IGdDrBPqz1O0v_UwCW-NJlbX9Hy9b3uJ11t28y2srmY,1062
9
- hydraflow-0.2.1.dist-info/RECORD,,