ml-dash 0.6.1__py3-none-any.whl → 0.6.2rc1__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 +2 -0
- ml_dash/experiment.py +83 -36
- ml_dash/files.py +932 -336
- ml_dash/run.py +85 -0
- ml_dash/storage.py +4 -2
- {ml_dash-0.6.1.dist-info → ml_dash-0.6.2rc1.dist-info}/METADATA +42 -15
- {ml_dash-0.6.1.dist-info → ml_dash-0.6.2rc1.dist-info}/RECORD +9 -8
- {ml_dash-0.6.1.dist-info → ml_dash-0.6.2rc1.dist-info}/WHEEL +1 -1
- {ml_dash-0.6.1.dist-info → ml_dash-0.6.2rc1.dist-info}/entry_points.txt +0 -0
ml_dash/run.py
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""
|
|
2
|
+
RUN - Global run configuration object for ML-Dash.
|
|
3
|
+
|
|
4
|
+
This module provides a global RUN object that serves as the single source
|
|
5
|
+
of truth for run/experiment metadata. Uses params-proto for configuration.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
from ml_dash import RUN
|
|
9
|
+
|
|
10
|
+
# Configure the run
|
|
11
|
+
RUN.name = "my-experiment"
|
|
12
|
+
RUN.project = "my-project"
|
|
13
|
+
|
|
14
|
+
# Use in templates
|
|
15
|
+
folder = "/experiments/{RUN.name}".format(RUN=RUN)
|
|
16
|
+
|
|
17
|
+
# With dxp singleton (RUN is auto-populated)
|
|
18
|
+
from ml_dash import dxp
|
|
19
|
+
with dxp.run:
|
|
20
|
+
# RUN.name, RUN.project, RUN.id, RUN.timestamp are set
|
|
21
|
+
dxp.log().info(f"Running {RUN.name}")
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
from datetime import datetime
|
|
25
|
+
from params_proto import proto
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@proto.prefix
|
|
29
|
+
class RUN:
|
|
30
|
+
"""
|
|
31
|
+
Global run configuration.
|
|
32
|
+
|
|
33
|
+
This class is the single source of truth for run metadata.
|
|
34
|
+
Configure it before starting an experiment, or let dxp auto-configure.
|
|
35
|
+
"""
|
|
36
|
+
# Core identifiers
|
|
37
|
+
name: str = "untitled" # Run/experiment name
|
|
38
|
+
project: str = "scratch" # Project name
|
|
39
|
+
|
|
40
|
+
# Auto-generated identifiers (populated at run.start())
|
|
41
|
+
id: str = None # Unique run ID (auto-generated)
|
|
42
|
+
timestamp: str = None # Run timestamp (same as id)
|
|
43
|
+
|
|
44
|
+
# Optional configuration
|
|
45
|
+
folder: str = None # Folder path with optional templates
|
|
46
|
+
description: str = None # Run description
|
|
47
|
+
|
|
48
|
+
@classmethod
|
|
49
|
+
def _generate_id(cls) -> str:
|
|
50
|
+
"""Generate a unique run ID based on current timestamp."""
|
|
51
|
+
return datetime.utcnow().strftime("%Y%m%d_%H%M%S")
|
|
52
|
+
|
|
53
|
+
@classmethod
|
|
54
|
+
def _init_run(cls) -> None:
|
|
55
|
+
"""Initialize run ID and timestamp if not already set."""
|
|
56
|
+
if cls.id is None:
|
|
57
|
+
cls.id = cls._generate_id()
|
|
58
|
+
cls.timestamp = cls.id
|
|
59
|
+
|
|
60
|
+
@classmethod
|
|
61
|
+
def _format(cls, template: str) -> str:
|
|
62
|
+
"""
|
|
63
|
+
Format a template string with RUN values.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
template: String with {RUN.attr} placeholders
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
Formatted string with placeholders replaced
|
|
70
|
+
|
|
71
|
+
Example:
|
|
72
|
+
RUN._format("/experiments/{RUN.name}_{RUN.id}")
|
|
73
|
+
# -> "/experiments/my-exp_20241219_143022"
|
|
74
|
+
"""
|
|
75
|
+
return template.format(RUN=cls)
|
|
76
|
+
|
|
77
|
+
@classmethod
|
|
78
|
+
def _reset(cls) -> None:
|
|
79
|
+
"""Reset RUN to defaults (for testing or new runs)."""
|
|
80
|
+
cls.name = "untitled"
|
|
81
|
+
cls.project = "scratch"
|
|
82
|
+
cls.id = None
|
|
83
|
+
cls.timestamp = None
|
|
84
|
+
cls.folder = None
|
|
85
|
+
cls.description = None
|
ml_dash/storage.py
CHANGED
|
@@ -627,7 +627,8 @@ class LocalStorage:
|
|
|
627
627
|
FileNotFoundError: If file not found
|
|
628
628
|
"""
|
|
629
629
|
experiment_dir = self._get_experiment_dir(project, experiment)
|
|
630
|
-
|
|
630
|
+
files_dir = experiment_dir / "files"
|
|
631
|
+
metadata_file = files_dir / ".files_metadata.json"
|
|
631
632
|
|
|
632
633
|
if not metadata_file.exists():
|
|
633
634
|
raise FileNotFoundError(f"File {file_id} not found")
|
|
@@ -689,7 +690,8 @@ class LocalStorage:
|
|
|
689
690
|
FileNotFoundError: If file not found
|
|
690
691
|
"""
|
|
691
692
|
experiment_dir = self._get_experiment_dir(project, experiment)
|
|
692
|
-
|
|
693
|
+
files_dir = experiment_dir / "files"
|
|
694
|
+
metadata_file = files_dir / ".files_metadata.json"
|
|
693
695
|
|
|
694
696
|
if not metadata_file.exists():
|
|
695
697
|
raise FileNotFoundError(f"File {file_id} not found")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: ml-dash
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.2rc1
|
|
4
4
|
Summary: ML experiment tracking and data storage
|
|
5
5
|
Keywords: machine-learning,experiment-tracking,mlops,data-storage
|
|
6
6
|
Author: Ge Yang, Tom Tao
|
|
@@ -43,6 +43,7 @@ Requires-Dist: imageio-ffmpeg>=0.4.9
|
|
|
43
43
|
Requires-Dist: scikit-image>=0.21.0
|
|
44
44
|
Requires-Dist: rich>=13.0.0
|
|
45
45
|
Requires-Dist: cryptography>=42.0.0
|
|
46
|
+
Requires-Dist: params-proto>=3.0.0rc12
|
|
46
47
|
Requires-Dist: keyring>=25.0.0 ; extra == 'auth'
|
|
47
48
|
Requires-Dist: qrcode>=8.0.0 ; extra == 'auth'
|
|
48
49
|
Requires-Dist: pytest>=8.0.0 ; extra == 'dev'
|
|
@@ -67,12 +68,13 @@ Description-Content-Type: text/markdown
|
|
|
67
68
|
|
|
68
69
|
# ML-Dash
|
|
69
70
|
|
|
70
|
-
A simple and flexible SDK for ML experiment
|
|
71
|
+
A simple and flexible SDK for ML experiment tracking and data storage.
|
|
71
72
|
|
|
72
73
|
## Features
|
|
73
74
|
|
|
74
|
-
- **Three Usage Styles**:
|
|
75
|
+
- **Three Usage Styles**: Pre-configured singleton (dxp), context manager, or direct instantiation
|
|
75
76
|
- **Dual Operation Modes**: Remote (API server) or local (filesystem)
|
|
77
|
+
- **OAuth2 Authentication**: Secure device flow authentication for CLI and SDK
|
|
76
78
|
- **Auto-creation**: Automatically creates namespace, project, and folder hierarchy
|
|
77
79
|
- **Upsert Behavior**: Updates existing experiments or creates new ones
|
|
78
80
|
- **Experiment Lifecycle**: Automatic status tracking (RUNNING, COMPLETED, FAILED, CANCELLED)
|
|
@@ -91,23 +93,48 @@ A simple and flexible SDK for ML experiment metricing and data storage.
|
|
|
91
93
|
<td>
|
|
92
94
|
|
|
93
95
|
```bash
|
|
94
|
-
uv add ml-dash
|
|
96
|
+
uv add ml-dash==0.6.2rc1
|
|
95
97
|
```
|
|
96
98
|
|
|
97
99
|
</td>
|
|
98
100
|
<td>
|
|
99
101
|
|
|
100
102
|
```bash
|
|
101
|
-
pip install ml-dash
|
|
103
|
+
pip install ml-dash==0.6.2rc1
|
|
102
104
|
```
|
|
103
105
|
|
|
104
106
|
</td>
|
|
105
107
|
</tr>
|
|
106
108
|
</table>
|
|
107
109
|
|
|
108
|
-
##
|
|
110
|
+
## Quick Start
|
|
109
111
|
|
|
110
|
-
###
|
|
112
|
+
### 1. Authenticate (Required for Remote Mode)
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
ml-dash login
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
This opens your browser for secure OAuth2 authentication. Your credentials are stored securely in your system keychain.
|
|
119
|
+
|
|
120
|
+
### 2. Start Tracking Experiments
|
|
121
|
+
|
|
122
|
+
#### Option A: Use the Pre-configured Singleton (Easiest)
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from ml_dash import dxp
|
|
126
|
+
|
|
127
|
+
# Start experiment (uploads to https://api.dash.ml by default)
|
|
128
|
+
with dxp.run:
|
|
129
|
+
dxp.log().info("Training started")
|
|
130
|
+
dxp.params.set(learning_rate=0.001, batch_size=32)
|
|
131
|
+
|
|
132
|
+
for epoch in range(10):
|
|
133
|
+
loss = train_one_epoch()
|
|
134
|
+
dxp.metrics("loss").append(value=loss, epoch=epoch)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
#### Option B: Create Your Own Experiment
|
|
111
138
|
|
|
112
139
|
```python
|
|
113
140
|
from ml_dash import Experiment
|
|
@@ -115,13 +142,13 @@ from ml_dash import Experiment
|
|
|
115
142
|
with Experiment(
|
|
116
143
|
name="my-experiment",
|
|
117
144
|
project="my-project",
|
|
118
|
-
remote="https://api.dash.ml"
|
|
119
|
-
|
|
120
|
-
)
|
|
121
|
-
|
|
145
|
+
remote="https://api.dash.ml" # token auto-loaded
|
|
146
|
+
).run as experiment:
|
|
147
|
+
experiment.log().info("Hello!")
|
|
148
|
+
experiment.params.set(lr=0.001)
|
|
122
149
|
```
|
|
123
150
|
|
|
124
|
-
|
|
151
|
+
#### Option C: Local Mode (No Authentication Required)
|
|
125
152
|
|
|
126
153
|
```python
|
|
127
154
|
from ml_dash import Experiment
|
|
@@ -130,11 +157,11 @@ with Experiment(
|
|
|
130
157
|
name="my-experiment",
|
|
131
158
|
project="my-project",
|
|
132
159
|
local_path=".ml-dash"
|
|
133
|
-
) as experiment:
|
|
134
|
-
|
|
160
|
+
).run as experiment:
|
|
161
|
+
experiment.log().info("Running locally")
|
|
135
162
|
```
|
|
136
163
|
|
|
137
|
-
See [
|
|
164
|
+
See [docs/getting-started.md](docs/getting-started.md) for more examples.
|
|
138
165
|
|
|
139
166
|
## Development Setup
|
|
140
167
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
ml_dash/__init__.py,sha256=
|
|
1
|
+
ml_dash/__init__.py,sha256=JJlSut9U_nixMsZxaqj9QQK0J3WUckGis7ouOQegWmw,2260
|
|
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
|
|
@@ -15,15 +15,16 @@ ml_dash/cli_commands/logout.py,sha256=lTUUNyRXqvo61qNkCd4KBrPUujDAHnNqsHkU6bHie0
|
|
|
15
15
|
ml_dash/cli_commands/upload.py,sha256=4O9iZOQDOiiBBsoDG1Cr8BqeBGSZZSfc3i-5FERjFtU,46439
|
|
16
16
|
ml_dash/client.py,sha256=0jM3HzNyFy-QBN7ZLXQTuiIuiTuh4K1Zdldb4Eny0NY,29531
|
|
17
17
|
ml_dash/config.py,sha256=aNqX_HT2Yo-BzjFexQ97gQK9xOiBUwuJJ65dKM3oJjs,3481
|
|
18
|
-
ml_dash/experiment.py,sha256=
|
|
19
|
-
ml_dash/files.py,sha256=
|
|
18
|
+
ml_dash/experiment.py,sha256=4mbJ6nul-k5Il1z0zjX2mmw56TbhWkeW4KyUa5DHvcU,35410
|
|
19
|
+
ml_dash/files.py,sha256=OCcGI2RHV5iO5BSWObCpz-GVJ2-wGFAgTqGGhDSesbQ,45168
|
|
20
20
|
ml_dash/log.py,sha256=0yXaNnFwYeBI3tRLHX3kkqWRpg0MbSGwmgjnOfsElCk,5350
|
|
21
21
|
ml_dash/metric.py,sha256=vz3YwO1YBWZ797l7TzD5m9WwNBBXlrATyRRzSti8QS0,17194
|
|
22
22
|
ml_dash/params.py,sha256=S4wHQfv0EQRXRrFbKLuEKTQOLp5eqnALcIk1pZNroBM,9124
|
|
23
23
|
ml_dash/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
24
|
ml_dash/remote_auto_start.py,sha256=BAsTu41e9SboeSCn9N2vn4ftoYeUVklcAcNM45HJVGA,1610
|
|
25
|
-
ml_dash/
|
|
26
|
-
ml_dash
|
|
27
|
-
ml_dash-0.6.
|
|
28
|
-
ml_dash-0.6.
|
|
29
|
-
ml_dash-0.6.
|
|
25
|
+
ml_dash/run.py,sha256=JwLigo2trdkwVrv-eCP4q9enSxLzla8jXeHXd6ZvNFk,2449
|
|
26
|
+
ml_dash/storage.py,sha256=iaFpH-2eK-Vd_b1lPpOQHxJI9GGkehB9g7pT7-r3nu4,39553
|
|
27
|
+
ml_dash-0.6.2rc1.dist-info/WHEEL,sha256=ELhySV62sOro8I5wRaLaF3TWxhBpkcDkdZUdAYLy_Hk,78
|
|
28
|
+
ml_dash-0.6.2rc1.dist-info/entry_points.txt,sha256=dYs2EHX1uRNO7AQGNnVaJJpgiy0Z9q7tiy4fHSyaf3Q,46
|
|
29
|
+
ml_dash-0.6.2rc1.dist-info/METADATA,sha256=d_EDyVjjcNTdhItUZYayP--dzrIchFsIOOBJ4aWrKSU,7206
|
|
30
|
+
ml_dash-0.6.2rc1.dist-info/RECORD,,
|
|
File without changes
|