ml-dash 0.6.1__tar.gz → 0.6.2rc1__tar.gz
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-0.6.1 → ml_dash-0.6.2rc1}/PKG-INFO +42 -15
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/README.md +40 -14
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/pyproject.toml +2 -1
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/__init__.py +2 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/experiment.py +83 -36
- ml_dash-0.6.2rc1/src/ml_dash/files.py +1381 -0
- ml_dash-0.6.2rc1/src/ml_dash/run.py +85 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/storage.py +4 -2
- ml_dash-0.6.1/src/ml_dash/files.py +0 -785
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/LICENSE +0 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/auth/__init__.py +0 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/auth/constants.py +0 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/auth/device_flow.py +0 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/auth/device_secret.py +0 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/auth/exceptions.py +0 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/auth/token_storage.py +0 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/auto_start.py +0 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/cli.py +0 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/cli_commands/__init__.py +0 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/cli_commands/download.py +0 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/cli_commands/list.py +0 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/cli_commands/login.py +0 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/cli_commands/logout.py +0 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/cli_commands/upload.py +0 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/client.py +0 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/config.py +0 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/log.py +0 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/metric.py +0 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/params.py +0 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/py.typed +0 -0
- {ml_dash-0.6.1 → ml_dash-0.6.2rc1}/src/ml_dash/remote_auto_start.py +0 -0
|
@@ -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,11 +1,12 @@
|
|
|
1
1
|
# ML-Dash
|
|
2
2
|
|
|
3
|
-
A simple and flexible SDK for ML experiment
|
|
3
|
+
A simple and flexible SDK for ML experiment tracking and data storage.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **Three Usage Styles**:
|
|
7
|
+
- **Three Usage Styles**: Pre-configured singleton (dxp), context manager, or direct instantiation
|
|
8
8
|
- **Dual Operation Modes**: Remote (API server) or local (filesystem)
|
|
9
|
+
- **OAuth2 Authentication**: Secure device flow authentication for CLI and SDK
|
|
9
10
|
- **Auto-creation**: Automatically creates namespace, project, and folder hierarchy
|
|
10
11
|
- **Upsert Behavior**: Updates existing experiments or creates new ones
|
|
11
12
|
- **Experiment Lifecycle**: Automatic status tracking (RUNNING, COMPLETED, FAILED, CANCELLED)
|
|
@@ -24,23 +25,48 @@ A simple and flexible SDK for ML experiment metricing and data storage.
|
|
|
24
25
|
<td>
|
|
25
26
|
|
|
26
27
|
```bash
|
|
27
|
-
uv add ml-dash
|
|
28
|
+
uv add ml-dash==0.6.2rc1
|
|
28
29
|
```
|
|
29
30
|
|
|
30
31
|
</td>
|
|
31
32
|
<td>
|
|
32
33
|
|
|
33
34
|
```bash
|
|
34
|
-
pip install ml-dash
|
|
35
|
+
pip install ml-dash==0.6.2rc1
|
|
35
36
|
```
|
|
36
37
|
|
|
37
38
|
</td>
|
|
38
39
|
</tr>
|
|
39
40
|
</table>
|
|
40
41
|
|
|
41
|
-
##
|
|
42
|
+
## Quick Start
|
|
42
43
|
|
|
43
|
-
###
|
|
44
|
+
### 1. Authenticate (Required for Remote Mode)
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
ml-dash login
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
This opens your browser for secure OAuth2 authentication. Your credentials are stored securely in your system keychain.
|
|
51
|
+
|
|
52
|
+
### 2. Start Tracking Experiments
|
|
53
|
+
|
|
54
|
+
#### Option A: Use the Pre-configured Singleton (Easiest)
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from ml_dash import dxp
|
|
58
|
+
|
|
59
|
+
# Start experiment (uploads to https://api.dash.ml by default)
|
|
60
|
+
with dxp.run:
|
|
61
|
+
dxp.log().info("Training started")
|
|
62
|
+
dxp.params.set(learning_rate=0.001, batch_size=32)
|
|
63
|
+
|
|
64
|
+
for epoch in range(10):
|
|
65
|
+
loss = train_one_epoch()
|
|
66
|
+
dxp.metrics("loss").append(value=loss, epoch=epoch)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
#### Option B: Create Your Own Experiment
|
|
44
70
|
|
|
45
71
|
```python
|
|
46
72
|
from ml_dash import Experiment
|
|
@@ -48,13 +74,13 @@ from ml_dash import Experiment
|
|
|
48
74
|
with Experiment(
|
|
49
75
|
name="my-experiment",
|
|
50
76
|
project="my-project",
|
|
51
|
-
remote="https://api.dash.ml"
|
|
52
|
-
|
|
53
|
-
)
|
|
54
|
-
|
|
77
|
+
remote="https://api.dash.ml" # token auto-loaded
|
|
78
|
+
).run as experiment:
|
|
79
|
+
experiment.log().info("Hello!")
|
|
80
|
+
experiment.params.set(lr=0.001)
|
|
55
81
|
```
|
|
56
82
|
|
|
57
|
-
|
|
83
|
+
#### Option C: Local Mode (No Authentication Required)
|
|
58
84
|
|
|
59
85
|
```python
|
|
60
86
|
from ml_dash import Experiment
|
|
@@ -63,11 +89,11 @@ with Experiment(
|
|
|
63
89
|
name="my-experiment",
|
|
64
90
|
project="my-project",
|
|
65
91
|
local_path=".ml-dash"
|
|
66
|
-
) as experiment:
|
|
67
|
-
|
|
92
|
+
).run as experiment:
|
|
93
|
+
experiment.log().info("Running locally")
|
|
68
94
|
```
|
|
69
95
|
|
|
70
|
-
See [
|
|
96
|
+
See [docs/getting-started.md](docs/getting-started.md) for more examples.
|
|
71
97
|
|
|
72
98
|
## Development Setup
|
|
73
99
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "ml-dash"
|
|
3
|
-
version = "0.6.
|
|
3
|
+
version = "0.6.2rc1"
|
|
4
4
|
description = "ML experiment tracking and data storage"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.9"
|
|
@@ -31,6 +31,7 @@ dependencies = [
|
|
|
31
31
|
"scikit-image>=0.21.0",
|
|
32
32
|
"rich>=13.0.0",
|
|
33
33
|
"cryptography>=42.0.0",
|
|
34
|
+
"params-proto>=3.0.0rc12",
|
|
34
35
|
]
|
|
35
36
|
|
|
36
37
|
[project.scripts]
|
|
@@ -51,6 +51,7 @@ from .client import RemoteClient
|
|
|
51
51
|
from .storage import LocalStorage
|
|
52
52
|
from .log import LogLevel, LogBuilder
|
|
53
53
|
from .params import ParametersBuilder
|
|
54
|
+
from .run import RUN
|
|
54
55
|
from .auto_start import dxp
|
|
55
56
|
|
|
56
57
|
__version__ = "0.1.0"
|
|
@@ -65,6 +66,7 @@ __all__ = [
|
|
|
65
66
|
"LogLevel",
|
|
66
67
|
"LogBuilder",
|
|
67
68
|
"ParametersBuilder",
|
|
69
|
+
"RUN",
|
|
68
70
|
"dxp",
|
|
69
71
|
]
|
|
70
72
|
|
|
@@ -17,7 +17,8 @@ from .client import RemoteClient
|
|
|
17
17
|
from .storage import LocalStorage
|
|
18
18
|
from .log import LogLevel, LogBuilder
|
|
19
19
|
from .params import ParametersBuilder
|
|
20
|
-
from .files import
|
|
20
|
+
from .files import FilesAccessor, BindrsBuilder
|
|
21
|
+
from .run import RUN
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
class OperationMode(Enum):
|
|
@@ -121,28 +122,13 @@ class RunManager:
|
|
|
121
122
|
"Set folder before calling start() or entering 'with' block."
|
|
122
123
|
)
|
|
123
124
|
|
|
124
|
-
#
|
|
125
|
+
# Check if this is a template (contains {RUN.) or static folder
|
|
125
126
|
if value and '{RUN.' in value:
|
|
126
|
-
#
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
# Supports: {RUN.name}, {RUN.project}, {RUN.id}, {RUN.timestamp}
|
|
132
|
-
replacements = {
|
|
133
|
-
'{RUN.name}': f"{self._experiment.name}_{run_timestamp}", # Unique name with timestamp
|
|
134
|
-
'{RUN.project}': self._experiment.project,
|
|
135
|
-
'{RUN.id}': run_timestamp, # Just the timestamp
|
|
136
|
-
'{RUN.timestamp}': run_timestamp, # Alias for id
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
# Replace all template variables
|
|
140
|
-
for template, replacement in replacements.items():
|
|
141
|
-
if template in value:
|
|
142
|
-
value = value.replace(template, replacement)
|
|
143
|
-
|
|
144
|
-
# Update the folder on the experiment
|
|
145
|
-
self._experiment.folder = value
|
|
127
|
+
# Store the template - it will be formatted when the run starts
|
|
128
|
+
self._experiment._folder_template = value
|
|
129
|
+
else:
|
|
130
|
+
# Static folder - set directly
|
|
131
|
+
self._experiment.folder = value
|
|
146
132
|
|
|
147
133
|
def __enter__(self) -> "Experiment":
|
|
148
134
|
"""Context manager entry - starts the experiment."""
|
|
@@ -240,7 +226,7 @@ class Experiment:
|
|
|
240
226
|
self.project = project
|
|
241
227
|
self.description = description
|
|
242
228
|
self.tags = tags
|
|
243
|
-
self.
|
|
229
|
+
self._bindrs_list = bindrs
|
|
244
230
|
self.folder = folder
|
|
245
231
|
self._write_protected = _write_protected
|
|
246
232
|
self.metadata = metadata
|
|
@@ -264,6 +250,7 @@ class Experiment:
|
|
|
264
250
|
self._experiment_data: Optional[Dict[str, Any]] = None
|
|
265
251
|
self._is_open = False
|
|
266
252
|
self._metrics_manager: Optional['MetricsManager'] = None # Cached metrics manager
|
|
253
|
+
self._folder_template: Optional[str] = None # Template for folder path
|
|
267
254
|
|
|
268
255
|
if self.mode in (OperationMode.REMOTE, OperationMode.HYBRID):
|
|
269
256
|
# api_key can be None - RemoteClient will auto-load from storage
|
|
@@ -284,6 +271,16 @@ class Experiment:
|
|
|
284
271
|
if self._is_open:
|
|
285
272
|
return self
|
|
286
273
|
|
|
274
|
+
# Initialize RUN with experiment values
|
|
275
|
+
RUN.name = self.name
|
|
276
|
+
RUN.project = self.project
|
|
277
|
+
RUN.description = self.description
|
|
278
|
+
RUN._init_run() # Generate id and timestamp
|
|
279
|
+
|
|
280
|
+
# Format folder template if present
|
|
281
|
+
if self._folder_template:
|
|
282
|
+
self.folder = RUN._format(self._folder_template)
|
|
283
|
+
|
|
287
284
|
if self._client:
|
|
288
285
|
# Remote mode: create/update experiment via API
|
|
289
286
|
response = self._client.create_or_update_experiment(
|
|
@@ -291,7 +288,7 @@ class Experiment:
|
|
|
291
288
|
name=self.name,
|
|
292
289
|
description=self.description,
|
|
293
290
|
tags=self.tags,
|
|
294
|
-
bindrs=self.
|
|
291
|
+
bindrs=self._bindrs_list,
|
|
295
292
|
folder=self.folder,
|
|
296
293
|
write_protected=self._write_protected,
|
|
297
294
|
metadata=self.metadata,
|
|
@@ -306,7 +303,7 @@ class Experiment:
|
|
|
306
303
|
name=self.name,
|
|
307
304
|
description=self.description,
|
|
308
305
|
tags=self.tags,
|
|
309
|
-
bindrs=self.
|
|
306
|
+
bindrs=self._bindrs_list,
|
|
310
307
|
folder=self.folder,
|
|
311
308
|
metadata=self.metadata,
|
|
312
309
|
)
|
|
@@ -341,6 +338,9 @@ class Experiment:
|
|
|
341
338
|
|
|
342
339
|
self._is_open = False
|
|
343
340
|
|
|
341
|
+
# Reset RUN for next experiment
|
|
342
|
+
RUN._reset()
|
|
343
|
+
|
|
344
344
|
@property
|
|
345
345
|
def run(self) -> RunManager:
|
|
346
346
|
"""
|
|
@@ -545,39 +545,86 @@ class Experiment:
|
|
|
545
545
|
else:
|
|
546
546
|
print(formatted_message, file=sys.stdout)
|
|
547
547
|
|
|
548
|
-
|
|
548
|
+
@property
|
|
549
|
+
def files(self) -> FilesAccessor:
|
|
549
550
|
"""
|
|
550
|
-
Get a
|
|
551
|
+
Get a FilesAccessor for fluent file operations.
|
|
551
552
|
|
|
552
553
|
Returns:
|
|
553
|
-
|
|
554
|
+
FilesAccessor instance for chaining
|
|
554
555
|
|
|
555
556
|
Raises:
|
|
556
557
|
RuntimeError: If experiment is not open
|
|
557
558
|
|
|
558
559
|
Examples:
|
|
559
560
|
# Upload file
|
|
560
|
-
experiment.files(
|
|
561
|
+
experiment.files("checkpoints").save(net, to="checkpoint.pt")
|
|
561
562
|
|
|
562
563
|
# List files
|
|
563
|
-
files = experiment.files().list()
|
|
564
|
-
files = experiment.files(
|
|
564
|
+
files = experiment.files("/some/location").list()
|
|
565
|
+
files = experiment.files("/models").list()
|
|
565
566
|
|
|
566
567
|
# Download file
|
|
567
|
-
experiment.files(
|
|
568
|
+
experiment.files("some.text").download()
|
|
569
|
+
experiment.files("some.text").download(to="./model.pt")
|
|
570
|
+
|
|
571
|
+
# Download Files via Glob Pattern
|
|
572
|
+
file_paths = experiment.files("images").list("*.png")
|
|
573
|
+
experiment.files("images").download("*.png")
|
|
574
|
+
|
|
575
|
+
# This is equivalent to downloading to a directory
|
|
576
|
+
experiment.files.download("images/*.png", to="local_images")
|
|
577
|
+
|
|
578
|
+
# Delete files
|
|
579
|
+
experiment.files("some.text").delete()
|
|
580
|
+
experiment.files.delete("some.text")
|
|
581
|
+
|
|
582
|
+
# Specific File Types
|
|
583
|
+
dxp.files.save_text("content", to="view.yaml")
|
|
584
|
+
dxp.files.save_json(dict(hey="yo"), to="config.json")
|
|
585
|
+
dxp.files.save_blob(b"xxx", to="data.bin")
|
|
586
|
+
"""
|
|
587
|
+
if not self._is_open:
|
|
588
|
+
raise RuntimeError(
|
|
589
|
+
"Experiment not started. Use 'with experiment.run:' or call experiment.run.start() first.\n"
|
|
590
|
+
"Example:\n"
|
|
591
|
+
" with dxp.run:\n"
|
|
592
|
+
" dxp.files('path').save()"
|
|
593
|
+
)
|
|
594
|
+
|
|
595
|
+
return FilesAccessor(self)
|
|
596
|
+
|
|
597
|
+
def bindrs(self, bindr_name: str) -> BindrsBuilder:
|
|
598
|
+
"""
|
|
599
|
+
Get a BindrsBuilder for working with file collections (bindrs).
|
|
600
|
+
|
|
601
|
+
Bindrs are collections of files that can span multiple prefixes.
|
|
602
|
+
|
|
603
|
+
Args:
|
|
604
|
+
bindr_name: Name of the bindr (collection)
|
|
605
|
+
|
|
606
|
+
Returns:
|
|
607
|
+
BindrsBuilder instance for chaining
|
|
608
|
+
|
|
609
|
+
Raises:
|
|
610
|
+
RuntimeError: If experiment is not open
|
|
611
|
+
|
|
612
|
+
Examples:
|
|
613
|
+
# List files in a bindr
|
|
614
|
+
file_paths = experiment.bindrs("some-bindr").list()
|
|
568
615
|
|
|
569
|
-
|
|
570
|
-
|
|
616
|
+
Note:
|
|
617
|
+
This is a placeholder for future bindr functionality.
|
|
571
618
|
"""
|
|
572
619
|
if not self._is_open:
|
|
573
620
|
raise RuntimeError(
|
|
574
621
|
"Experiment not started. Use 'with experiment.run:' or call experiment.run.start() first.\n"
|
|
575
622
|
"Example:\n"
|
|
576
623
|
" with dxp.run:\n"
|
|
577
|
-
" dxp.
|
|
624
|
+
" files = dxp.bindrs('my-bindr').list()"
|
|
578
625
|
)
|
|
579
626
|
|
|
580
|
-
return
|
|
627
|
+
return BindrsBuilder(self, bindr_name)
|
|
581
628
|
|
|
582
629
|
def _upload_file(
|
|
583
630
|
self,
|