ml-dash 0.6.4__py3-none-any.whl → 0.6.6__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.
- ml_dash/__init__.py +1 -2
- ml_dash/auto_start.py +1 -4
- ml_dash/cli.py +7 -1
- ml_dash/cli_commands/create.py +145 -0
- ml_dash/cli_commands/upload.py +17 -4
- ml_dash/client.py +378 -18
- ml_dash/experiment.py +231 -357
- ml_dash/run.py +92 -3
- ml_dash/storage.py +0 -2
- {ml_dash-0.6.4.dist-info → ml_dash-0.6.6.dist-info}/METADATA +1 -1
- {ml_dash-0.6.4.dist-info → ml_dash-0.6.6.dist-info}/RECORD +13 -12
- {ml_dash-0.6.4.dist-info → ml_dash-0.6.6.dist-info}/WHEEL +0 -0
- {ml_dash-0.6.4.dist-info → ml_dash-0.6.6.dist-info}/entry_points.txt +0 -0
ml_dash/run.py
CHANGED
|
@@ -22,14 +22,43 @@ Usage:
|
|
|
22
22
|
exp.logs.info(f"Running {RUN.name}")
|
|
23
23
|
"""
|
|
24
24
|
|
|
25
|
+
import functools
|
|
25
26
|
import os
|
|
26
27
|
import sys
|
|
28
|
+
import typing
|
|
27
29
|
from datetime import datetime
|
|
28
30
|
from pathlib import Path
|
|
29
|
-
from typing import Union
|
|
31
|
+
from typing import Optional, Union
|
|
30
32
|
|
|
31
33
|
from params_proto import EnvVar, proto
|
|
32
34
|
|
|
35
|
+
|
|
36
|
+
def requires_open(func):
|
|
37
|
+
"""
|
|
38
|
+
Decorator that ensures the experiment is open before executing a method.
|
|
39
|
+
|
|
40
|
+
Raises:
|
|
41
|
+
RuntimeError: If experiment is not started
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
@functools.wraps(func)
|
|
45
|
+
def wrapper(self, *args, **kwargs):
|
|
46
|
+
if not self._is_open:
|
|
47
|
+
raise RuntimeError(
|
|
48
|
+
"Experiment not started. Use 'with experiment.run:' or call experiment.run.start() first.\n"
|
|
49
|
+
"Example:\n"
|
|
50
|
+
" with dxp.run:\n"
|
|
51
|
+
" dxp.params.set(lr=0.001)"
|
|
52
|
+
)
|
|
53
|
+
return func(self, *args, **kwargs)
|
|
54
|
+
|
|
55
|
+
return wrapper
|
|
56
|
+
|
|
57
|
+
if typing.TYPE_CHECKING:
|
|
58
|
+
from .client import RemoteClient
|
|
59
|
+
from .experiment import Experiment
|
|
60
|
+
from .storage import LocalStorage
|
|
61
|
+
|
|
33
62
|
PROJECT_ROOT_FILES = ("pyproject.toml", "requirements.txt", "setup.py", "setup.cfg")
|
|
34
63
|
|
|
35
64
|
|
|
@@ -77,12 +106,19 @@ def find_project_root(
|
|
|
77
106
|
@proto.prefix
|
|
78
107
|
class RUN:
|
|
79
108
|
"""
|
|
80
|
-
Global Experiment Run Configuration
|
|
109
|
+
Global Experiment Run Configuration and
|
|
110
|
+
Lifecycle manager for experiments
|
|
81
111
|
|
|
82
112
|
This class is the single source of truth for experiment metadata.
|
|
83
113
|
Configure it before starting an experiment, or through the Experiment
|
|
84
114
|
constructor.
|
|
85
115
|
|
|
116
|
+
Supports three usage patterns:
|
|
117
|
+
1. Method calls: experiment.run.start(), experiment.run.complete()
|
|
118
|
+
2. Context manager: with Experiment(...).run as exp:
|
|
119
|
+
3. Decorator: @exp.run or @Experiment(...).run
|
|
120
|
+
|
|
121
|
+
|
|
86
122
|
Default prefix template:
|
|
87
123
|
{project}/{now:%Y/%m-%d}/{path_stem}/{job_name}
|
|
88
124
|
|
|
@@ -156,10 +192,21 @@ class RUN:
|
|
|
156
192
|
debug = "pydevd" in sys.modules
|
|
157
193
|
"set to True automatically for pyCharm"
|
|
158
194
|
|
|
195
|
+
_experiment: "Experiment" = None
|
|
196
|
+
_client: Optional["RemoteClient"] = None
|
|
197
|
+
_storage: Optional["LocalStorage"] = None
|
|
198
|
+
|
|
199
|
+
# Prefix components (parsed from prefix)
|
|
200
|
+
owner: Optional[str] = None
|
|
201
|
+
name: Optional[str] = None
|
|
202
|
+
_folder_path: Optional[str] = None
|
|
203
|
+
|
|
159
204
|
def __post_init__(self):
|
|
160
205
|
"""
|
|
206
|
+
|
|
161
207
|
Initialize RUN with auto-detected prefix from entry path.
|
|
162
208
|
|
|
209
|
+
|
|
163
210
|
Args:
|
|
164
211
|
entry: Path to entry file/directory (e.g., __file__ or directory
|
|
165
212
|
containing sweep.jsonl). If not provided, uses caller's
|
|
@@ -179,7 +226,6 @@ class RUN:
|
|
|
179
226
|
RUN.__post_init__(entry=__file__)
|
|
180
227
|
# Result: RUN.prefix = "vision/resnet", RUN.name = "resnet"
|
|
181
228
|
"""
|
|
182
|
-
|
|
183
229
|
# Use provided entry or try to auto-detect from caller
|
|
184
230
|
if self.entry is None:
|
|
185
231
|
import inspect
|
|
@@ -221,6 +267,49 @@ class RUN:
|
|
|
221
267
|
# for k, v in data.items():
|
|
222
268
|
# print(f"> {k:>30}: {v}")
|
|
223
269
|
|
|
270
|
+
# Parse prefix into components: {owner}/{project}/path.../[name]
|
|
271
|
+
if self.prefix:
|
|
272
|
+
self._folder_path = self.prefix
|
|
273
|
+
parts = self.prefix.strip("/").split("/")
|
|
274
|
+
if len(parts) >= 2:
|
|
275
|
+
self.owner = parts[0]
|
|
276
|
+
self.project = parts[1]
|
|
277
|
+
# self.name is the last segment
|
|
278
|
+
self.name = parts[-1] if len(parts) > 2 else parts[1]
|
|
279
|
+
|
|
280
|
+
def start(self) -> "Experiment":
|
|
281
|
+
"""
|
|
282
|
+
Start the experiment (sets status to RUNNING).
|
|
283
|
+
|
|
284
|
+
Returns:
|
|
285
|
+
The experiment instance for chaining
|
|
286
|
+
"""
|
|
287
|
+
return self._experiment._open()
|
|
288
|
+
|
|
289
|
+
def complete(self) -> None:
|
|
290
|
+
"""Mark experiment as completed (status: COMPLETED)."""
|
|
291
|
+
self._experiment._close(status="COMPLETED")
|
|
292
|
+
|
|
293
|
+
def fail(self) -> None:
|
|
294
|
+
"""Mark experiment as failed (status: FAILED)."""
|
|
295
|
+
self._experiment._close(status="FAILED")
|
|
296
|
+
|
|
297
|
+
def cancel(self) -> None:
|
|
298
|
+
"""Mark experiment as cancelled (status: CANCELLED)."""
|
|
299
|
+
self._experiment._close(status="CANCELLED")
|
|
300
|
+
|
|
301
|
+
def __enter__(self) -> "Experiment":
|
|
302
|
+
"""Context manager entry - starts the experiment."""
|
|
303
|
+
return self.start()
|
|
304
|
+
|
|
305
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
306
|
+
"""Context manager exit - completes or fails the experiment."""
|
|
307
|
+
if exc_type is not None:
|
|
308
|
+
self.fail()
|
|
309
|
+
else:
|
|
310
|
+
self.complete()
|
|
311
|
+
return False
|
|
312
|
+
|
|
224
313
|
|
|
225
314
|
if __name__ == "__main__":
|
|
226
315
|
RUN.description = ""
|
ml_dash/storage.py
CHANGED
|
@@ -84,7 +84,6 @@ class LocalStorage:
|
|
|
84
84
|
|
|
85
85
|
def create_experiment(
|
|
86
86
|
self,
|
|
87
|
-
owner: str,
|
|
88
87
|
project: str,
|
|
89
88
|
prefix: str,
|
|
90
89
|
description: Optional[str] = None,
|
|
@@ -99,7 +98,6 @@ class LocalStorage:
|
|
|
99
98
|
where prefix = owner/project/folder_1/.../exp_name
|
|
100
99
|
|
|
101
100
|
Args:
|
|
102
|
-
owner: Owner/user (extracted from prefix, kept for API compatibility)
|
|
103
101
|
project: Project name (extracted from prefix, kept for API compatibility)
|
|
104
102
|
prefix: Full experiment path (owner/project/folder_1/.../exp_name)
|
|
105
103
|
description: Optional description
|
|
@@ -1,33 +1,34 @@
|
|
|
1
|
-
ml_dash/__init__.py,sha256=
|
|
1
|
+
ml_dash/__init__.py,sha256=B1oYUXt2DnCctz5nWEqkg1M_XtbJNxaOPxbg54C0Vdc,1555
|
|
2
2
|
ml_dash/auth/__init__.py,sha256=3lwM-Y8UBHPU1gFW2JNpmXlPVTnkGudWLKNFFKulQfo,1200
|
|
3
3
|
ml_dash/auth/constants.py,sha256=ku4QzQUMNjvyJwjy7AUdywMAZd59jXSxNHZxDiagUWU,280
|
|
4
4
|
ml_dash/auth/device_flow.py,sha256=DQOdPNlZCuU1umZOA_A6WXdRM3zWphnyo9IntToBl_A,7921
|
|
5
5
|
ml_dash/auth/device_secret.py,sha256=qUsz6M9S1GEIukvmz57eJEp57srSx74O4MU9mZEeDlE,1158
|
|
6
6
|
ml_dash/auth/exceptions.py,sha256=IeBwUzoaTyFtPwd4quFOIel49inIzuabe_ChEeEXEWI,725
|
|
7
7
|
ml_dash/auth/token_storage.py,sha256=L18W8J7D1LlCDlY3Q32l0RXeNh0o7YVDQeeGYm64Dgw,8163
|
|
8
|
-
ml_dash/auto_start.py,sha256=
|
|
9
|
-
ml_dash/cli.py,sha256=
|
|
8
|
+
ml_dash/auto_start.py,sha256=FHTTui33bxfk5rHf-VY2RFcd2JQ_LsNpkUu7Qtpc-GY,1721
|
|
9
|
+
ml_dash/cli.py,sha256=X8LsQA8Wfa1XuXsbvePaGo6NYer7f8CNzy33VT3jrqg,2740
|
|
10
10
|
ml_dash/cli_commands/__init__.py,sha256=bjAmV7MsW-bhtW_4SnLJ0Cfkt9h82vMDC8ebW1Ke8KE,38
|
|
11
11
|
ml_dash/cli_commands/api.py,sha256=NekZEJGWNpIfB6YrsrOw7kw7rZKjVudwgJWPZIy6ANQ,4535
|
|
12
|
+
ml_dash/cli_commands/create.py,sha256=i6LPA6vefpHUeXncBNzQsLnwF5EM2uF6IX4g7vTDYXo,4400
|
|
12
13
|
ml_dash/cli_commands/download.py,sha256=LeZXjQSEPIxZALuo90fj8RHjFWIbtGPE0F625sD3cU8,28054
|
|
13
14
|
ml_dash/cli_commands/list.py,sha256=oc_yJXFhsvGgr3JedG2j7747yX69Qc546geIi4DQ54k,16129
|
|
14
15
|
ml_dash/cli_commands/login.py,sha256=zX-urtUrfzg2qOGtKNYQgj6UloN9kzj4zEO6h_xwuNs,6782
|
|
15
16
|
ml_dash/cli_commands/logout.py,sha256=lTUUNyRXqvo61qNkCd4KBrPUujDAHnNqsHkU6bHie0U,1332
|
|
16
17
|
ml_dash/cli_commands/profile.py,sha256=BaSM6BAN3YM4tw95iKV_nypKZxwsB3PoAAejQcYip5E,2351
|
|
17
|
-
ml_dash/cli_commands/upload.py,sha256=
|
|
18
|
-
ml_dash/client.py,sha256=
|
|
18
|
+
ml_dash/cli_commands/upload.py,sha256=1kTmnw4hAevl5mtB1GKlzEh2sPoudv0LTUNhCg0dIXs,45459
|
|
19
|
+
ml_dash/client.py,sha256=VYOW-JNtHEonHoeS7InbyMXKRSrWFcRjo7onhqkGXKg,54659
|
|
19
20
|
ml_dash/config.py,sha256=oz2xvoBh2X_xUXWr92cPD5nFxXMT5LxVNypv5B5O0fA,3116
|
|
20
|
-
ml_dash/experiment.py,sha256=
|
|
21
|
+
ml_dash/experiment.py,sha256=JCLSWJMOSHQ-dAfR4hOwB07BpNoXzbWTY9lk4VOVRKY,37678
|
|
21
22
|
ml_dash/files.py,sha256=bihUHKpdknytLGuGgkcvhh585nziZrvYjiHl6rHnoD0,49227
|
|
22
23
|
ml_dash/log.py,sha256=E-DLg0vejVLLEyShJ_r0LneDMI0XU7XTH5iKWYJe9jI,5298
|
|
23
24
|
ml_dash/metric.py,sha256=ghD1jnuv6dbjV1Jlo7q0mx9UEzpdto2Y1-oDWrSfg04,25809
|
|
24
25
|
ml_dash/params.py,sha256=pPFvknJAJX5uhckzjO1r-HNnKbQFFKDISFmOXNET5eY,9046
|
|
25
26
|
ml_dash/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
27
|
ml_dash/remote_auto_start.py,sha256=5fvQDHv1CWEKFb6WAa5_uyEInwV_SvotXjOO_6i6ZKE,1687
|
|
27
|
-
ml_dash/run.py,sha256=
|
|
28
|
+
ml_dash/run.py,sha256=_a1l5qswwMgrhvajx_lI-I5IXhfHDeH3hfLAJ7Uk_Gs,8847
|
|
28
29
|
ml_dash/snowflake.py,sha256=14rEpRU5YltsmmmZW0EMUy_hdv5S5ME9gWVtmdmwfiU,4917
|
|
29
|
-
ml_dash/storage.py,sha256=
|
|
30
|
-
ml_dash-0.6.
|
|
31
|
-
ml_dash-0.6.
|
|
32
|
-
ml_dash-0.6.
|
|
33
|
-
ml_dash-0.6.
|
|
30
|
+
ml_dash/storage.py,sha256=jJ0mYCeBIMQ_dQeNLaCiW0fndsliG68w-TmCI1HyYZc,32926
|
|
31
|
+
ml_dash-0.6.6.dist-info/WHEEL,sha256=z-mOpxbJHqy3cq6SvUThBZdaLGFZzdZPtgWLcP2NKjQ,79
|
|
32
|
+
ml_dash-0.6.6.dist-info/entry_points.txt,sha256=dYs2EHX1uRNO7AQGNnVaJJpgiy0Z9q7tiy4fHSyaf3Q,46
|
|
33
|
+
ml_dash-0.6.6.dist-info/METADATA,sha256=ARlHyG-ZdMBqW-WSJjjaKuqwo2bm2M5X7ENkZ-yI0Z0,7203
|
|
34
|
+
ml_dash-0.6.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|