hydraflow 0.14.3__py3-none-any.whl → 0.15.0__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 +3 -13
- hydraflow/core/context.py +12 -32
- hydraflow/core/io.py +36 -115
- hydraflow/core/main.py +3 -3
- hydraflow/core/run.py +341 -0
- hydraflow/core/run_collection.py +525 -0
- hydraflow/core/run_info.py +84 -0
- {hydraflow-0.14.3.dist-info → hydraflow-0.15.0.dist-info}/METADATA +12 -10
- hydraflow-0.15.0.dist-info/RECORD +21 -0
- hydraflow/core/config.py +0 -122
- hydraflow/core/mlflow.py +0 -174
- hydraflow/core/param.py +0 -165
- hydraflow/entities/__init__.py +0 -0
- hydraflow/entities/run_collection.py +0 -583
- hydraflow/entities/run_data.py +0 -61
- hydraflow/entities/run_info.py +0 -36
- hydraflow-0.14.3.dist-info/RECORD +0 -25
- {hydraflow-0.14.3.dist-info → hydraflow-0.15.0.dist-info}/WHEEL +0 -0
- {hydraflow-0.14.3.dist-info → hydraflow-0.15.0.dist-info}/entry_points.txt +0 -0
- {hydraflow-0.14.3.dist-info → hydraflow-0.15.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,583 +0,0 @@
|
|
1
|
-
"""Provide a collection of MLflow runs.
|
2
|
-
|
3
|
-
This module includes the `RunCollection` class, which serves as a container
|
4
|
-
for multiple MLflow `Run` instances, and various methods to filter and
|
5
|
-
retrieve these runs.
|
6
|
-
|
7
|
-
Key Features:
|
8
|
-
- **Run Management**: The `RunCollection` class allows for easy management of
|
9
|
-
multiple MLflow runs, providing methods to filter and retrieve runs based
|
10
|
-
on various criteria.
|
11
|
-
- **Filtering**: Support filtering runs based on specific configurations
|
12
|
-
and parameters, enabling users to easily find runs that match certain conditions.
|
13
|
-
- **Retrieval**: Users can retrieve specific runs, including the first, last, or any
|
14
|
-
run that matches a given configuration.
|
15
|
-
- **Artifact Handling**: Provide methods to access and manipulate the
|
16
|
-
artifacts associated with each run, including retrieving artifact URIs and
|
17
|
-
directories.
|
18
|
-
"""
|
19
|
-
|
20
|
-
from __future__ import annotations
|
21
|
-
|
22
|
-
from dataclasses import dataclass, field
|
23
|
-
from itertools import chain
|
24
|
-
from typing import TYPE_CHECKING, Any, overload
|
25
|
-
|
26
|
-
import hydraflow.core.param
|
27
|
-
from hydraflow.core.config import iter_params, select_config, select_overrides
|
28
|
-
from hydraflow.core.io import load_config
|
29
|
-
from hydraflow.core.param import get_params, get_values
|
30
|
-
|
31
|
-
from .run_data import RunCollectionData
|
32
|
-
from .run_info import RunCollectionInfo
|
33
|
-
|
34
|
-
if TYPE_CHECKING:
|
35
|
-
from collections.abc import Callable, Iterator
|
36
|
-
from typing import Any
|
37
|
-
|
38
|
-
from mlflow.entities.run import Run
|
39
|
-
|
40
|
-
|
41
|
-
@dataclass
|
42
|
-
class RunCollection:
|
43
|
-
"""Represent a collection of MLflow runs.
|
44
|
-
|
45
|
-
Provide methods to interact with the runs, such as filtering,
|
46
|
-
retrieving specific runs, and accessing run information.
|
47
|
-
|
48
|
-
Key Features:
|
49
|
-
- Filtering: Easily filter runs based on various criteria.
|
50
|
-
- Retrieval: Access specific runs by index or through methods.
|
51
|
-
- Metadata: Access run metadata and associated information.
|
52
|
-
"""
|
53
|
-
|
54
|
-
_runs: list[Run]
|
55
|
-
"""A list of MLflow `Run` instances."""
|
56
|
-
|
57
|
-
_info: RunCollectionInfo = field(init=False)
|
58
|
-
"""An instance of `RunCollectionInfo`."""
|
59
|
-
|
60
|
-
_data: RunCollectionData = field(init=False)
|
61
|
-
"""An instance of `RunCollectionData`."""
|
62
|
-
|
63
|
-
def __post_init__(self) -> None:
|
64
|
-
self._info = RunCollectionInfo(self)
|
65
|
-
self._data = RunCollectionData(self)
|
66
|
-
|
67
|
-
def __repr__(self) -> str:
|
68
|
-
return f"{self.__class__.__name__}({len(self)})"
|
69
|
-
|
70
|
-
def __len__(self) -> int:
|
71
|
-
return len(self._runs)
|
72
|
-
|
73
|
-
def __iter__(self) -> Iterator[Run]:
|
74
|
-
return iter(self._runs)
|
75
|
-
|
76
|
-
@overload
|
77
|
-
def __getitem__(self, index: int) -> Run: ...
|
78
|
-
|
79
|
-
@overload
|
80
|
-
def __getitem__(self, index: slice) -> RunCollection: ...
|
81
|
-
|
82
|
-
def __getitem__(self, index: int | slice) -> Run | RunCollection:
|
83
|
-
if isinstance(index, slice):
|
84
|
-
return self.__class__(self._runs[index])
|
85
|
-
|
86
|
-
return self._runs[index]
|
87
|
-
|
88
|
-
def __contains__(self, run: Run) -> bool:
|
89
|
-
return run in self._runs
|
90
|
-
|
91
|
-
def __bool__(self) -> bool:
|
92
|
-
return bool(self._runs)
|
93
|
-
|
94
|
-
def __add__(self, other: RunCollection) -> RunCollection:
|
95
|
-
"""Add another `RunCollection` to this one.
|
96
|
-
|
97
|
-
Args:
|
98
|
-
other (RunCollection): The `RunCollection` to add.
|
99
|
-
|
100
|
-
Returns:
|
101
|
-
A new `RunCollection` instance with the runs from both collections.
|
102
|
-
|
103
|
-
"""
|
104
|
-
return self.__class__(self._runs + other._runs)
|
105
|
-
|
106
|
-
def __sub__(self, other: RunCollection) -> RunCollection:
|
107
|
-
"""Subtract another `RunCollection` from this one.
|
108
|
-
|
109
|
-
Args:
|
110
|
-
other (RunCollection): The `RunCollection` to subtract.
|
111
|
-
|
112
|
-
Returns:
|
113
|
-
A new `RunCollection` instance with the runs that are in this collection
|
114
|
-
but not in the other.
|
115
|
-
|
116
|
-
"""
|
117
|
-
runs = [run for run in self._runs if run not in other._runs]
|
118
|
-
return self.__class__(runs)
|
119
|
-
|
120
|
-
@property
|
121
|
-
def info(self) -> RunCollectionInfo:
|
122
|
-
"""An instance of `RunCollectionInfo`."""
|
123
|
-
return self._info
|
124
|
-
|
125
|
-
@property
|
126
|
-
def data(self) -> RunCollectionData:
|
127
|
-
"""An instance of `RunCollectionData`."""
|
128
|
-
return self._data
|
129
|
-
|
130
|
-
def one(self) -> Run:
|
131
|
-
"""Get the only `Run` instance in the collection.
|
132
|
-
|
133
|
-
Returns:
|
134
|
-
The only `Run` instance in the collection.
|
135
|
-
|
136
|
-
Raises:
|
137
|
-
ValueError: If the collection does not contain exactly one run.
|
138
|
-
|
139
|
-
"""
|
140
|
-
if len(self._runs) != 1:
|
141
|
-
raise ValueError("The collection does not contain exactly one run.")
|
142
|
-
|
143
|
-
return self._runs[0]
|
144
|
-
|
145
|
-
def try_one(self) -> Run | None:
|
146
|
-
"""Try to get the only `Run` instance in the collection.
|
147
|
-
|
148
|
-
Returns:
|
149
|
-
The only `Run` instance in the collection, or None if the collection
|
150
|
-
does not contain exactly one run.
|
151
|
-
|
152
|
-
"""
|
153
|
-
return self._runs[0] if len(self._runs) == 1 else None
|
154
|
-
|
155
|
-
def first(self) -> Run:
|
156
|
-
"""Get the first `Run` instance in the collection.
|
157
|
-
|
158
|
-
Returns:
|
159
|
-
The first `Run` instance in the collection.
|
160
|
-
|
161
|
-
Raises:
|
162
|
-
ValueError: If the collection is empty.
|
163
|
-
|
164
|
-
"""
|
165
|
-
if not self._runs:
|
166
|
-
raise ValueError("The collection is empty.")
|
167
|
-
|
168
|
-
return self._runs[0]
|
169
|
-
|
170
|
-
def try_first(self) -> Run | None:
|
171
|
-
"""Try to get the first `Run` instance in the collection.
|
172
|
-
|
173
|
-
Returns:
|
174
|
-
The first `Run` instance in the collection, or None if the collection
|
175
|
-
is empty.
|
176
|
-
|
177
|
-
"""
|
178
|
-
return self._runs[0] if self._runs else None
|
179
|
-
|
180
|
-
def last(self) -> Run:
|
181
|
-
"""Get the last `Run` instance in the collection.
|
182
|
-
|
183
|
-
Returns:
|
184
|
-
The last `Run` instance in the collection.
|
185
|
-
|
186
|
-
Raises:
|
187
|
-
ValueError: If the collection is empty.
|
188
|
-
|
189
|
-
"""
|
190
|
-
if not self._runs:
|
191
|
-
raise ValueError("The collection is empty.")
|
192
|
-
|
193
|
-
return self._runs[-1]
|
194
|
-
|
195
|
-
def try_last(self) -> Run | None:
|
196
|
-
"""Try to get the last `Run` instance in the collection.
|
197
|
-
|
198
|
-
Returns:
|
199
|
-
The last `Run` instance in the collection, or None if the collection
|
200
|
-
is empty.
|
201
|
-
|
202
|
-
"""
|
203
|
-
return self._runs[-1] if self._runs else None
|
204
|
-
|
205
|
-
def filter(
|
206
|
-
self,
|
207
|
-
config: object | Callable[[Run], bool] | None = None,
|
208
|
-
*,
|
209
|
-
select: list[str] | None = None,
|
210
|
-
overrides: list[str] | None = None,
|
211
|
-
status: str | list[str] | int | list[int] | None = None,
|
212
|
-
**kwargs,
|
213
|
-
) -> RunCollection:
|
214
|
-
"""Filter the `Run` instances based on the provided configuration.
|
215
|
-
|
216
|
-
This method filters the runs in the collection according to the
|
217
|
-
specified configuration object and additional key-value pairs. The
|
218
|
-
configuration object and key-value pairs should contain key-value pairs
|
219
|
-
that correspond to the parameters of the runs. Only the runs that match
|
220
|
-
all the specified parameters will be included in the returned
|
221
|
-
`RunCollection` object.
|
222
|
-
|
223
|
-
The filtering supports:
|
224
|
-
- Exact matches for single values.
|
225
|
-
- Membership checks for lists of values.
|
226
|
-
- Range checks for tuples of two values (inclusive of both the lower
|
227
|
-
and upper bound).
|
228
|
-
- Callable that takes a `Run` object and returns a boolean value.
|
229
|
-
|
230
|
-
Args:
|
231
|
-
config (object | Callable[[Run], bool] | None): The configuration object
|
232
|
-
to filter the runs. This can be any object that provides key-value
|
233
|
-
pairs through the `iter_params` function, or a callable that
|
234
|
-
takes a `Run` object and returns a boolean value.
|
235
|
-
select (list[str] | None): The list of parameters to select.
|
236
|
-
overrides (list[str] | None): The list of overrides to filter the
|
237
|
-
runs.
|
238
|
-
status (str | list[str] | int | list[int] | None): The status of the
|
239
|
-
runs to filter.
|
240
|
-
**kwargs: Additional key-value pairs to filter the runs.
|
241
|
-
|
242
|
-
Returns:
|
243
|
-
A new `RunCollection` object containing the filtered runs.
|
244
|
-
|
245
|
-
"""
|
246
|
-
return RunCollection(
|
247
|
-
filter_runs(
|
248
|
-
self._runs,
|
249
|
-
config,
|
250
|
-
select=select,
|
251
|
-
overrides=overrides,
|
252
|
-
status=status,
|
253
|
-
**kwargs,
|
254
|
-
),
|
255
|
-
)
|
256
|
-
|
257
|
-
def get(
|
258
|
-
self,
|
259
|
-
config: object | Callable[[Run], bool] | None = None,
|
260
|
-
**kwargs,
|
261
|
-
) -> Run:
|
262
|
-
"""Retrieve a specific `Run` instance based on the provided configuration.
|
263
|
-
|
264
|
-
This method filters the runs in the collection according to the
|
265
|
-
specified configuration object and returns the run that matches the
|
266
|
-
provided parameters. If no run matches the criteria, or if more than
|
267
|
-
one run matches the criteria, a `ValueError` is raised.
|
268
|
-
|
269
|
-
Args:
|
270
|
-
config (object | Callable[[Run], bool] | None): The configuration object
|
271
|
-
to identify the run. This can be any object that provides key-value
|
272
|
-
pairs through the `iter_params` function, or a callable that
|
273
|
-
takes a `Run` object and returns a boolean value.
|
274
|
-
**kwargs: Additional key-value pairs to filter the runs.
|
275
|
-
|
276
|
-
Returns:
|
277
|
-
The `Run` instance that matches the provided configuration.
|
278
|
-
|
279
|
-
Raises:
|
280
|
-
ValueError: If no run matches the criteria or if more than one run
|
281
|
-
matches the criteria.
|
282
|
-
|
283
|
-
See Also:
|
284
|
-
`filter`: Perform the actual filtering logic.
|
285
|
-
|
286
|
-
"""
|
287
|
-
try:
|
288
|
-
return self.filter(config, **kwargs).one()
|
289
|
-
except ValueError:
|
290
|
-
msg = "The filtered collection does not contain exactly one run."
|
291
|
-
raise ValueError(msg)
|
292
|
-
|
293
|
-
def try_get(
|
294
|
-
self,
|
295
|
-
config: object | Callable[[Run], bool] | None = None,
|
296
|
-
**kwargs,
|
297
|
-
) -> Run | None:
|
298
|
-
"""Try to get a specific `Run` instance based on the provided configuration.
|
299
|
-
|
300
|
-
This method filters the runs in the collection according to the
|
301
|
-
specified configuration object and returns the run that matches the
|
302
|
-
provided parameters. If no run matches the criteria, None is returned.
|
303
|
-
If more than one run matches the criteria, a `ValueError` is raised.
|
304
|
-
|
305
|
-
Args:
|
306
|
-
config (object | Callable[[Run], bool] | None): The configuration object
|
307
|
-
to identify the run. This can be any object that provides key-value
|
308
|
-
pairs through the `iter_params` function, or a callable that
|
309
|
-
takes a `Run` object and returns a boolean value.
|
310
|
-
**kwargs: Additional key-value pairs to filter the runs.
|
311
|
-
|
312
|
-
Returns:
|
313
|
-
The `Run` instance that matches the provided configuration, or None
|
314
|
-
if no runs match the criteria.
|
315
|
-
|
316
|
-
Raises:
|
317
|
-
ValueError: If more than one run matches the criteria.
|
318
|
-
|
319
|
-
See Also:
|
320
|
-
`filter`: Perform the actual filtering logic.
|
321
|
-
|
322
|
-
"""
|
323
|
-
return self.filter(config, **kwargs).try_one()
|
324
|
-
|
325
|
-
def get_param_names(self) -> list[str]:
|
326
|
-
"""Get the parameter names from the runs.
|
327
|
-
|
328
|
-
This method extracts the unique parameter names from the provided list
|
329
|
-
of runs. It iterates through each run and collects the parameter names
|
330
|
-
into a set to ensure uniqueness.
|
331
|
-
|
332
|
-
Returns:
|
333
|
-
A list of unique parameter names.
|
334
|
-
|
335
|
-
"""
|
336
|
-
param_names = set()
|
337
|
-
|
338
|
-
for run in self:
|
339
|
-
for param in run.data.params:
|
340
|
-
param_names.add(param)
|
341
|
-
|
342
|
-
return list(param_names)
|
343
|
-
|
344
|
-
def get_param_dict(self, *, drop_const: bool = False) -> dict[str, list[str]]:
|
345
|
-
"""Get the parameter dictionary from the list of runs.
|
346
|
-
|
347
|
-
This method extracts the parameter names and their corresponding values
|
348
|
-
from the provided list of runs. It iterates through each run and
|
349
|
-
collects the parameter values into a dictionary where the keys are
|
350
|
-
parameter names and the values are lists of parameter values.
|
351
|
-
|
352
|
-
Args:
|
353
|
-
drop_const (bool): If True, drop the parameter values that are constant
|
354
|
-
across all runs.
|
355
|
-
|
356
|
-
Returns:
|
357
|
-
A dictionary where the keys are parameter names and the values are
|
358
|
-
lists of parameter values.
|
359
|
-
|
360
|
-
"""
|
361
|
-
params = {}
|
362
|
-
|
363
|
-
for name in self.get_param_names():
|
364
|
-
it = (run.data.params[name] for run in self if name in run.data.params)
|
365
|
-
unique_values = sorted(set(it))
|
366
|
-
if not drop_const or len(unique_values) > 1:
|
367
|
-
params[name] = unique_values
|
368
|
-
|
369
|
-
return params
|
370
|
-
|
371
|
-
def groupby(
|
372
|
-
self,
|
373
|
-
names: str | list[str],
|
374
|
-
) -> dict[str | None | tuple[str | None, ...], RunCollection]:
|
375
|
-
"""Group runs by specified parameter names.
|
376
|
-
|
377
|
-
Group the runs in the collection based on the values of the
|
378
|
-
specified parameters. Each unique combination of parameter values will
|
379
|
-
form a key in the returned dictionary.
|
380
|
-
|
381
|
-
Args:
|
382
|
-
names (str | list[str]): The names of the parameters to group by.
|
383
|
-
This can be a single parameter name or multiple names provided
|
384
|
-
as separate arguments or as a list.
|
385
|
-
|
386
|
-
Returns:
|
387
|
-
dict[str | None | tuple[str | None, ...], RunCollection]: A
|
388
|
-
dictionary where the keys are tuples of parameter values and the
|
389
|
-
values are `RunCollection` objects containing the runs that match
|
390
|
-
those parameter values.
|
391
|
-
|
392
|
-
"""
|
393
|
-
grouped_runs: dict[str | None | tuple[str | None, ...], list[Run]] = {}
|
394
|
-
is_list = isinstance(names, list)
|
395
|
-
for run in self._runs:
|
396
|
-
key = get_params(run, names)
|
397
|
-
if not is_list:
|
398
|
-
key = key[0]
|
399
|
-
grouped_runs.setdefault(key, []).append(run)
|
400
|
-
|
401
|
-
return {key: RunCollection(runs) for key, runs in grouped_runs.items()}
|
402
|
-
|
403
|
-
def sort(
|
404
|
-
self,
|
405
|
-
*,
|
406
|
-
key: Callable[[Run], Any] | None = None,
|
407
|
-
reverse: bool = False,
|
408
|
-
) -> None:
|
409
|
-
"""Sort the runs in the collection.
|
410
|
-
|
411
|
-
Sort the runs in the collection according to the provided key function
|
412
|
-
and optional reverse flag.
|
413
|
-
|
414
|
-
Args:
|
415
|
-
key (Callable[[Run], Any] | None): A function that takes a run and returns
|
416
|
-
a value to sort by.
|
417
|
-
reverse (bool): If True, sort in descending order.
|
418
|
-
|
419
|
-
"""
|
420
|
-
self._runs.sort(key=key or (lambda x: x.info.start_time), reverse=reverse)
|
421
|
-
|
422
|
-
def values(self, names: str | list[str]) -> list[Any]:
|
423
|
-
"""Get the values of specified parameters from the runs.
|
424
|
-
|
425
|
-
Args:
|
426
|
-
names (str | list[str]): The names of the parameters to get the values.
|
427
|
-
This can be a single parameter name or multiple names provided
|
428
|
-
as separate arguments or as a list.
|
429
|
-
|
430
|
-
Returns:
|
431
|
-
A list of values for the specified parameters.
|
432
|
-
|
433
|
-
"""
|
434
|
-
is_list = isinstance(names, list)
|
435
|
-
|
436
|
-
if isinstance(names, str):
|
437
|
-
names = [names]
|
438
|
-
|
439
|
-
config = load_config(self.first())
|
440
|
-
types = [type(v) for v in select_config(config, names).values()]
|
441
|
-
values = [get_values(run, names, types) for run in self]
|
442
|
-
|
443
|
-
if is_list:
|
444
|
-
return values
|
445
|
-
|
446
|
-
return [v[0] for v in values]
|
447
|
-
|
448
|
-
def sorted(
|
449
|
-
self,
|
450
|
-
names: str | list[str],
|
451
|
-
*,
|
452
|
-
reverse: bool = False,
|
453
|
-
) -> RunCollection:
|
454
|
-
"""Sort the runs in the collection by specified parameter names.
|
455
|
-
|
456
|
-
Sort the runs in the collection based on the values of the specified
|
457
|
-
parameters.
|
458
|
-
|
459
|
-
Args:
|
460
|
-
names (str | list[str]): The names of the parameters to sort by.
|
461
|
-
This can be a single parameter name or multiple names provided
|
462
|
-
as separate arguments or as a list.
|
463
|
-
reverse (bool): If True, sort in descending order.
|
464
|
-
|
465
|
-
"""
|
466
|
-
values = self.values(names)
|
467
|
-
index = sorted(range(len(self)), key=lambda i: values[i], reverse=reverse)
|
468
|
-
return RunCollection([self[i] for i in index])
|
469
|
-
|
470
|
-
|
471
|
-
def _param_matches(run: Run, key: str, value: Any) -> bool:
|
472
|
-
params = run.data.params
|
473
|
-
if key not in params:
|
474
|
-
return False
|
475
|
-
|
476
|
-
param = params[key]
|
477
|
-
if param == "None":
|
478
|
-
return value is None or value == "None"
|
479
|
-
|
480
|
-
return hydraflow.core.param.match(param, value)
|
481
|
-
|
482
|
-
|
483
|
-
def filter_runs(
|
484
|
-
runs: list[Run],
|
485
|
-
config: object | Callable[[Run], bool] | None = None,
|
486
|
-
*,
|
487
|
-
select: list[str] | None = None,
|
488
|
-
overrides: list[str] | None = None,
|
489
|
-
status: str | list[str] | int | list[int] | None = None,
|
490
|
-
**kwargs,
|
491
|
-
) -> list[Run]:
|
492
|
-
"""Filter the runs based on the provided configuration.
|
493
|
-
|
494
|
-
Filter the runs in the collection according to the
|
495
|
-
specified configuration object and additional key-value pairs.
|
496
|
-
The configuration object and key-value pairs should contain
|
497
|
-
key-value pairs that correspond to the parameters of the runs.
|
498
|
-
Only the runs that match all the specified parameters will
|
499
|
-
be included in the returned list of runs.
|
500
|
-
|
501
|
-
The filtering supports:
|
502
|
-
- Exact matches for single values.
|
503
|
-
- Membership checks for lists of values.
|
504
|
-
- Range checks for tuples of two values (inclusive of both the lower and
|
505
|
-
upper bound).
|
506
|
-
|
507
|
-
Args:
|
508
|
-
runs (list[Run]): The list of runs to filter.
|
509
|
-
config (object | Callable[[Run], bool] | None, optional): The
|
510
|
-
configuration object to filter the runs. This can be any object
|
511
|
-
that provides key-value pairs through the `iter_params` function.
|
512
|
-
This can also be a callable that takes a `Run` object and returns
|
513
|
-
a boolean value. Defaults to None.
|
514
|
-
select (list[str] | None, optional): The list of parameters to select.
|
515
|
-
Defaults to None.
|
516
|
-
overrides (list[str] | None, optional): The list of overrides to filter the
|
517
|
-
runs. Defaults to None.
|
518
|
-
status (str | list[str] | RunStatus | list[RunStatus] | None, optional): The
|
519
|
-
status of the runs to filter. Defaults to None.
|
520
|
-
**kwargs: Additional key-value pairs to filter the runs.
|
521
|
-
|
522
|
-
Returns:
|
523
|
-
A list of runs that match the specified configuration and key-value pairs.
|
524
|
-
|
525
|
-
"""
|
526
|
-
if callable(config):
|
527
|
-
runs = [run for run in runs if config(run)]
|
528
|
-
|
529
|
-
else:
|
530
|
-
if overrides:
|
531
|
-
config = select_overrides(config, overrides)
|
532
|
-
elif select:
|
533
|
-
config = select_config(config, select)
|
534
|
-
|
535
|
-
for key, value in chain(iter_params(config), kwargs.items()):
|
536
|
-
runs = [run for run in runs if _param_matches(run, key, value)]
|
537
|
-
if not runs:
|
538
|
-
return []
|
539
|
-
|
540
|
-
if status is None:
|
541
|
-
return runs
|
542
|
-
|
543
|
-
return filter_runs_by_status(runs, status)
|
544
|
-
|
545
|
-
|
546
|
-
def filter_runs_by_status(
|
547
|
-
runs: list[Run],
|
548
|
-
status: str | list[str] | int | list[int],
|
549
|
-
) -> list[Run]:
|
550
|
-
"""Filter the runs based on the provided status.
|
551
|
-
|
552
|
-
Args:
|
553
|
-
runs (list[Run]): The list of runs to filter.
|
554
|
-
status (str | list[str] | int | list[int]): The status of the runs
|
555
|
-
to filter.
|
556
|
-
|
557
|
-
Returns:
|
558
|
-
A list of runs that match the specified status.
|
559
|
-
|
560
|
-
"""
|
561
|
-
from mlflow.entities import RunStatus
|
562
|
-
|
563
|
-
if isinstance(status, str):
|
564
|
-
if status.startswith("!"):
|
565
|
-
status = status[1:].lower()
|
566
|
-
return [run for run in runs if run.info.status.lower() != status]
|
567
|
-
|
568
|
-
status = [status]
|
569
|
-
|
570
|
-
elif isinstance(status, int):
|
571
|
-
status = [RunStatus.to_string(status)]
|
572
|
-
|
573
|
-
status = [_to_lower(s) for s in status]
|
574
|
-
return [run for run in runs if run.info.status.lower() in status]
|
575
|
-
|
576
|
-
|
577
|
-
def _to_lower(status: str | int) -> str:
|
578
|
-
from mlflow.entities import RunStatus
|
579
|
-
|
580
|
-
if isinstance(status, str):
|
581
|
-
return status.lower()
|
582
|
-
|
583
|
-
return RunStatus.to_string(status).lower()
|
hydraflow/entities/run_data.py
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
"""Provide data about `RunCollection` instances."""
|
2
|
-
|
3
|
-
from __future__ import annotations
|
4
|
-
|
5
|
-
from typing import TYPE_CHECKING
|
6
|
-
|
7
|
-
from hydraflow.core.config import iter_params
|
8
|
-
from hydraflow.core.io import load_config
|
9
|
-
|
10
|
-
if TYPE_CHECKING:
|
11
|
-
from collections.abc import Iterable
|
12
|
-
from typing import Any
|
13
|
-
|
14
|
-
from pandas import DataFrame
|
15
|
-
|
16
|
-
from .run_collection import RunCollection
|
17
|
-
|
18
|
-
|
19
|
-
class RunCollectionData:
|
20
|
-
"""Provide data about a `RunCollection` instance."""
|
21
|
-
|
22
|
-
def __init__(self, runs: RunCollection) -> None:
|
23
|
-
self._runs = runs
|
24
|
-
|
25
|
-
@property
|
26
|
-
def params(self) -> dict[str, list[str]]:
|
27
|
-
"""Get the parameters for each run in the collection."""
|
28
|
-
return _to_dict(run.data.params for run in self._runs)
|
29
|
-
|
30
|
-
@property
|
31
|
-
def metrics(self) -> dict[str, list[float]]:
|
32
|
-
"""Get the metrics for each run in the collection."""
|
33
|
-
return _to_dict(run.data.metrics for run in self._runs)
|
34
|
-
|
35
|
-
@property
|
36
|
-
def config(self) -> DataFrame:
|
37
|
-
"""Get the runs' configurations as a DataFrame.
|
38
|
-
|
39
|
-
Returns:
|
40
|
-
A DataFrame containing the runs' configurations.
|
41
|
-
|
42
|
-
"""
|
43
|
-
from pandas import DataFrame
|
44
|
-
|
45
|
-
values = [dict(iter_params(load_config(r))) for r in self._runs]
|
46
|
-
return DataFrame(values)
|
47
|
-
|
48
|
-
|
49
|
-
def _to_dict(it: Iterable[dict[str, Any]]) -> dict[str, list[Any]]:
|
50
|
-
"""Convert an iterable of dictionaries to a dictionary of lists."""
|
51
|
-
data = list(it)
|
52
|
-
if not data:
|
53
|
-
return {}
|
54
|
-
|
55
|
-
keys = []
|
56
|
-
for d in data:
|
57
|
-
for key in d:
|
58
|
-
if key not in keys:
|
59
|
-
keys.append(key)
|
60
|
-
|
61
|
-
return {key: [x.get(key) for x in data] for key in keys}
|
hydraflow/entities/run_info.py
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
"""Provide information about `RunCollection` instances."""
|
2
|
-
|
3
|
-
from __future__ import annotations
|
4
|
-
|
5
|
-
from typing import TYPE_CHECKING
|
6
|
-
|
7
|
-
from hydraflow.core.io import get_artifact_dir
|
8
|
-
|
9
|
-
if TYPE_CHECKING:
|
10
|
-
from pathlib import Path
|
11
|
-
|
12
|
-
from .run_collection import RunCollection
|
13
|
-
|
14
|
-
|
15
|
-
class RunCollectionInfo:
|
16
|
-
"""Provide information about a `RunCollection` instance."""
|
17
|
-
|
18
|
-
_runs: RunCollection
|
19
|
-
|
20
|
-
def __init__(self, runs: RunCollection) -> None:
|
21
|
-
self._runs = runs
|
22
|
-
|
23
|
-
@property
|
24
|
-
def run_id(self) -> list[str]:
|
25
|
-
"""Get the run ID for each run in the collection."""
|
26
|
-
return [run.info.run_id for run in self._runs]
|
27
|
-
|
28
|
-
@property
|
29
|
-
def artifact_uri(self) -> list[str | None]:
|
30
|
-
"""Get the artifact URI for each run in the collection."""
|
31
|
-
return [run.info.artifact_uri for run in self._runs]
|
32
|
-
|
33
|
-
@property
|
34
|
-
def artifact_dir(self) -> list[Path]:
|
35
|
-
"""Get the artifact directory for each run in the collection."""
|
36
|
-
return [get_artifact_dir(run) for run in self._runs]
|
@@ -1,25 +0,0 @@
|
|
1
|
-
hydraflow/__init__.py,sha256=f2KO2iF7um-nNmayNyEr7TWG4UICOXy7YAN1d3qu0OY,936
|
2
|
-
hydraflow/cli.py,sha256=3rGr___wwp8KazjLGQ7JO_IgAMqLyMlcVSs_QJK7g0Y,3135
|
3
|
-
hydraflow/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
-
hydraflow/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
|
-
hydraflow/core/config.py,sha256=SJzjgsO_kzB78_whJ3lmy7GlZvTvwZONH1BJBn8zCuI,3817
|
6
|
-
hydraflow/core/context.py,sha256=L4OygMLbITwlWzq17Lh8VoXKKtjOJ3DBEVsBddKPSJ8,4741
|
7
|
-
hydraflow/core/io.py,sha256=Tch85xbdRao7rG9BMbRpc2Cq0glC8a8M87QDoyQ81p8,6926
|
8
|
-
hydraflow/core/main.py,sha256=dY8uUykS_AbzverrSWkXLyj98TjBPHAiMUf_l5met1U,5162
|
9
|
-
hydraflow/core/mlflow.py,sha256=OQJ3f2wkHJRb11ZK__HF4R8FyBEje7-NOqObpoanGhU,5704
|
10
|
-
hydraflow/core/param.py,sha256=LHU9j9_7oA99igasoOyKofKClVr9FmGA3UABJ-KmyS0,4538
|
11
|
-
hydraflow/entities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
12
|
-
hydraflow/entities/run_collection.py,sha256=4sfZWXaS7kqnVCo9GyB3pN6BaSUCkA-ZqSSl5JBLNhk,19682
|
13
|
-
hydraflow/entities/run_data.py,sha256=lz8HPxG0iz1Jf9FU6HTFW4gcAc3N2pgMyAPqAIK6I74,1644
|
14
|
-
hydraflow/entities/run_info.py,sha256=FRC6ICOlzB2u_xi_33Qs-YZLt677UotuNbYqI7XSmHY,1017
|
15
|
-
hydraflow/executor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
16
|
-
hydraflow/executor/aio.py,sha256=xXsmBPIPdBlopv_1h0FdtOvoKUcuW7PQeKCV2d_lN9I,2122
|
17
|
-
hydraflow/executor/conf.py,sha256=icGbLDh86KgkyiGXwDoEkmZpgAP3X8Jmu_PYqJoTooY,423
|
18
|
-
hydraflow/executor/io.py,sha256=yZMcBVmAbPZZ82cAXhgiJfj9p8WvHmzOCMBg_vtEVek,1509
|
19
|
-
hydraflow/executor/job.py,sha256=JX6xX9ffvHB7IiAVIfzVRjjnWKaPDxBgqdZf4ZO14CY,4651
|
20
|
-
hydraflow/executor/parser.py,sha256=_Rfund3FDgrXitTt_znsTpgEtMDqZ_ICynaB_Zje14Q,14561
|
21
|
-
hydraflow-0.14.3.dist-info/METADATA,sha256=Y5fO4HFC2fgqhQnkB5k4mwITsCrq3DCFCSKNJcpa1y4,7460
|
22
|
-
hydraflow-0.14.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
23
|
-
hydraflow-0.14.3.dist-info/entry_points.txt,sha256=XI0khPbpCIUo9UPqkNEpgh-kqK3Jy8T7L2VCWOdkbSM,48
|
24
|
-
hydraflow-0.14.3.dist-info/licenses/LICENSE,sha256=IGdDrBPqz1O0v_UwCW-NJlbX9Hy9b3uJ11t28y2srmY,1062
|
25
|
-
hydraflow-0.14.3.dist-info/RECORD,,
|