nextmv 1.0.0.dev2__py3-none-any.whl → 1.0.0.dev4__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.
- nextmv/__about__.py +1 -1
- nextmv/cli/CONTRIBUTING.md +81 -29
- nextmv/cli/cloud/__init__.py +2 -0
- nextmv/cli/cloud/acceptance/create.py +20 -22
- nextmv/cli/cloud/acceptance/delete.py +7 -8
- nextmv/cli/cloud/acceptance/get.py +9 -10
- nextmv/cli/cloud/acceptance/list.py +3 -3
- nextmv/cli/cloud/acceptance/update.py +6 -6
- nextmv/cli/cloud/account/__init__.py +3 -3
- nextmv/cli/cloud/account/create.py +11 -11
- nextmv/cli/cloud/account/delete.py +6 -7
- nextmv/cli/cloud/account/get.py +3 -3
- nextmv/cli/cloud/account/update.py +5 -5
- nextmv/cli/cloud/app/create.py +25 -26
- nextmv/cli/cloud/app/delete.py +5 -6
- nextmv/cli/cloud/app/exists.py +2 -2
- nextmv/cli/cloud/app/get.py +2 -2
- nextmv/cli/cloud/app/list.py +3 -3
- nextmv/cli/cloud/app/push.py +269 -45
- nextmv/cli/cloud/app/update.py +12 -12
- nextmv/cli/cloud/batch/create.py +26 -28
- nextmv/cli/cloud/batch/delete.py +5 -6
- nextmv/cli/cloud/batch/get.py +8 -8
- nextmv/cli/cloud/batch/list.py +3 -3
- nextmv/cli/cloud/batch/metadata.py +4 -4
- nextmv/cli/cloud/batch/update.py +6 -6
- nextmv/cli/cloud/data/__init__.py +1 -1
- nextmv/cli/cloud/data/upload.py +15 -15
- nextmv/cli/cloud/ensemble/__init__.py +2 -0
- nextmv/cli/cloud/ensemble/create.py +21 -22
- nextmv/cli/cloud/ensemble/delete.py +5 -6
- nextmv/cli/cloud/ensemble/get.py +4 -4
- nextmv/cli/cloud/ensemble/list.py +63 -0
- nextmv/cli/cloud/ensemble/update.py +9 -9
- nextmv/cli/cloud/input_set/create.py +20 -22
- nextmv/cli/cloud/input_set/get.py +3 -3
- nextmv/cli/cloud/input_set/list.py +3 -3
- nextmv/cli/cloud/input_set/update.py +24 -24
- nextmv/cli/cloud/instance/create.py +14 -15
- nextmv/cli/cloud/instance/delete.py +5 -6
- nextmv/cli/cloud/instance/exists.py +2 -2
- nextmv/cli/cloud/instance/get.py +2 -2
- nextmv/cli/cloud/instance/list.py +3 -3
- nextmv/cli/cloud/instance/update.py +14 -14
- nextmv/cli/cloud/managed_input/create.py +14 -16
- nextmv/cli/cloud/managed_input/delete.py +6 -7
- nextmv/cli/cloud/managed_input/get.py +3 -3
- nextmv/cli/cloud/managed_input/list.py +3 -3
- nextmv/cli/cloud/managed_input/update.py +9 -9
- nextmv/cli/cloud/run/cancel.py +2 -2
- nextmv/cli/cloud/run/create.py +32 -33
- nextmv/cli/cloud/run/get.py +8 -8
- nextmv/cli/cloud/run/input.py +4 -4
- nextmv/cli/cloud/run/list.py +6 -6
- nextmv/cli/cloud/run/logs.py +9 -10
- nextmv/cli/cloud/run/metadata.py +4 -4
- nextmv/cli/cloud/run/track.py +32 -33
- nextmv/cli/cloud/scenario/create.py +21 -21
- nextmv/cli/cloud/scenario/delete.py +5 -6
- nextmv/cli/cloud/scenario/get.py +8 -8
- nextmv/cli/cloud/scenario/list.py +3 -3
- nextmv/cli/cloud/scenario/metadata.py +4 -4
- nextmv/cli/cloud/scenario/update.py +6 -6
- nextmv/cli/cloud/secrets/create.py +17 -17
- nextmv/cli/cloud/secrets/delete.py +5 -6
- nextmv/cli/cloud/secrets/get.py +4 -4
- nextmv/cli/cloud/secrets/list.py +3 -3
- nextmv/cli/cloud/secrets/update.py +17 -20
- nextmv/cli/cloud/shadow/__init__.py +1 -1
- nextmv/cli/cloud/shadow/create.py +32 -32
- nextmv/cli/cloud/shadow/delete.py +5 -6
- nextmv/cli/cloud/shadow/get.py +2 -2
- nextmv/cli/cloud/shadow/list.py +3 -3
- nextmv/cli/cloud/shadow/metadata.py +4 -4
- nextmv/cli/cloud/shadow/start.py +3 -3
- nextmv/cli/cloud/shadow/stop.py +8 -10
- nextmv/cli/cloud/shadow/update.py +7 -6
- nextmv/cli/cloud/switchback/__init__.py +33 -0
- nextmv/cli/cloud/switchback/create.py +151 -0
- nextmv/cli/cloud/switchback/delete.py +67 -0
- nextmv/cli/cloud/switchback/get.py +62 -0
- nextmv/cli/cloud/switchback/list.py +63 -0
- nextmv/cli/cloud/switchback/metadata.py +68 -0
- nextmv/cli/cloud/switchback/start.py +43 -0
- nextmv/cli/cloud/switchback/stop.py +41 -0
- nextmv/cli/cloud/switchback/update.py +96 -0
- nextmv/cli/cloud/upload/create.py +2 -2
- nextmv/cli/cloud/version/create.py +9 -10
- nextmv/cli/cloud/version/delete.py +5 -6
- nextmv/cli/cloud/version/exists.py +2 -2
- nextmv/cli/cloud/version/get.py +2 -2
- nextmv/cli/cloud/version/list.py +3 -3
- nextmv/cli/cloud/version/update.py +8 -8
- nextmv/cli/community/clone.py +12 -10
- nextmv/cli/community/list.py +9 -9
- nextmv/cli/configuration/config.py +43 -10
- nextmv/cli/configuration/create.py +3 -3
- nextmv/cli/configuration/delete.py +7 -7
- nextmv/cli/configuration/list.py +3 -3
- nextmv/cli/confirm.py +32 -0
- nextmv/cli/main.py +27 -36
- nextmv/cli/message.py +2 -2
- nextmv/cli/options.py +14 -0
- nextmv/cli/version.py +1 -1
- nextmv/cloud/__init__.py +5 -0
- nextmv/cloud/application/__init__.py +192 -54
- nextmv/cloud/application/_batch_scenario.py +2 -2
- nextmv/cloud/application/_instance.py +2 -2
- nextmv/cloud/application/_managed_input.py +1 -1
- nextmv/cloud/application/_shadow.py +1 -1
- nextmv/cloud/application/_switchback.py +323 -0
- nextmv/cloud/application/_version.py +3 -2
- nextmv/cloud/shadow.py +43 -4
- nextmv/cloud/switchback.py +226 -0
- {nextmv-1.0.0.dev2.dist-info → nextmv-1.0.0.dev4.dist-info}/METADATA +1 -1
- nextmv-1.0.0.dev4.dist-info/RECORD +183 -0
- nextmv-1.0.0.dev2.dist-info/RECORD +0 -170
- {nextmv-1.0.0.dev2.dist-info → nextmv-1.0.0.dev4.dist-info}/WHEEL +0 -0
- {nextmv-1.0.0.dev2.dist-info → nextmv-1.0.0.dev4.dist-info}/entry_points.txt +0 -0
- {nextmv-1.0.0.dev2.dist-info → nextmv-1.0.0.dev4.dist-info}/licenses/LICENSE +0 -0
nextmv/cli/cloud/batch/create.py
CHANGED
|
@@ -109,7 +109,7 @@ def create(
|
|
|
109
109
|
"--wait",
|
|
110
110
|
"-w",
|
|
111
111
|
help="Wait for the batch experiment to complete. Results are printed to [magenta]stdout[/magenta]. "
|
|
112
|
-
"Specify output location with
|
|
112
|
+
"Specify output location with --output.",
|
|
113
113
|
rich_help_panel="Output control",
|
|
114
114
|
),
|
|
115
115
|
] = False,
|
|
@@ -122,21 +122,19 @@ def create(
|
|
|
122
122
|
configurations. Each run is defined by a combination of input, instance or
|
|
123
123
|
version, and optional configuration options.
|
|
124
124
|
|
|
125
|
-
Use the
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
results.
|
|
125
|
+
Use the --wait flag to wait for the batch experiment to complete, polling
|
|
126
|
+
for results. Using the --output flag will also activate waiting, and allows
|
|
127
|
+
you to specify a destination file for the results.
|
|
129
128
|
|
|
130
129
|
[bold][underline]Runs[/underline][/bold]
|
|
131
130
|
|
|
132
|
-
Runs are provided as [magenta]json[/magenta] objects using the
|
|
133
|
-
|
|
134
|
-
and configuration to use.
|
|
131
|
+
Runs are provided as [magenta]json[/magenta] objects using the --runs flag.
|
|
132
|
+
Each run defines what input, instance/version, and configuration to use.
|
|
135
133
|
|
|
136
134
|
You can provide runs in three ways:
|
|
137
135
|
- A single run as a [magenta]json[/magenta] object.
|
|
138
|
-
- Multiple runs by repeating the
|
|
139
|
-
- Multiple runs as a [magenta]json[/magenta] array in a single
|
|
136
|
+
- Multiple runs by repeating the --runs flag.
|
|
137
|
+
- Multiple runs as a [magenta]json[/magenta] array in a single --runs flag.
|
|
140
138
|
|
|
141
139
|
Each run must have the following fields:
|
|
142
140
|
- [magenta]input_id[/magenta]: ID of the input to use for this run
|
|
@@ -146,46 +144,46 @@ def create(
|
|
|
146
144
|
- [magenta]instance_id[/magenta] OR [magenta]version_id[/magenta]: Either an instance ID or
|
|
147
145
|
version ID must be provided (at least one required).
|
|
148
146
|
- [magenta]option_set[/magenta]: ID of the option set to use (optional).
|
|
149
|
-
Make sure to define the option sets using the
|
|
147
|
+
Make sure to define the option sets using the --option-sets flag.
|
|
150
148
|
- [magenta]input_set_id[/magenta]: ID of the input set (optional).
|
|
151
149
|
- [magenta]scenario_id[/magenta]: Scenario ID if part of a scenario test (optional).
|
|
152
150
|
- [magenta]repetition[/magenta]: Repetition number (optional).
|
|
153
151
|
|
|
154
152
|
Object format:
|
|
155
|
-
[
|
|
153
|
+
[dim]{
|
|
156
154
|
"input_id": "meadow-input-a1",
|
|
157
155
|
"instance_id": "bunny-hopper-v2",
|
|
158
156
|
"option_set": "speed-optimized",
|
|
159
157
|
"input_set_id": "spring-gardens"
|
|
160
|
-
}[/
|
|
158
|
+
}[/dim]
|
|
161
159
|
|
|
162
160
|
[bold][underline]Option Sets[/underline][/bold]
|
|
163
161
|
|
|
164
162
|
Option sets are provided as a [magenta]json[/magenta] object using the
|
|
165
|
-
|
|
163
|
+
--option-sets flag. Option sets define named collections of
|
|
166
164
|
runtime options that can be referenced by runs.
|
|
167
165
|
|
|
168
166
|
The option sets object is a dictionary where keys are option set IDs and
|
|
169
167
|
values are dictionaries of string key-value pairs representing the options.
|
|
170
168
|
|
|
171
169
|
Object format:
|
|
172
|
-
[
|
|
170
|
+
[dim]{
|
|
173
171
|
"speed-optimized": {"timeout": "30", "algorithm": "fast"},
|
|
174
172
|
"quality-focused": {"timeout": "300", "algorithm": "thorough"}
|
|
175
|
-
}[/
|
|
173
|
+
}[/dim]
|
|
176
174
|
|
|
177
175
|
[bold][underline]Examples[/underline][/bold]
|
|
178
176
|
|
|
179
177
|
- Create a batch experiment with a single run.
|
|
180
|
-
$ [
|
|
178
|
+
$ [dim]RUN='{
|
|
181
179
|
"input_id": "carrot-patch-a",
|
|
182
180
|
"instance_id": "warren-planner-v1"
|
|
183
181
|
}'
|
|
184
182
|
nextmv cloud batch create --app-id hare-app --batch-experiment-id bunny-hop-test \\
|
|
185
|
-
--name "Spring Meadow Routes" --input-set-id spring-gardens --runs "$RUN"[/
|
|
183
|
+
--name "Spring Meadow Routes" --input-set-id spring-gardens --runs "$RUN"[/dim]
|
|
186
184
|
|
|
187
185
|
- Create with multiple runs by repeating the flag.
|
|
188
|
-
$ [
|
|
186
|
+
$ [dim]RUN1='{
|
|
189
187
|
"input_id": "lettuce-field-1",
|
|
190
188
|
"instance_id": "hop-optimizer"
|
|
191
189
|
}'
|
|
@@ -195,10 +193,10 @@ def create(
|
|
|
195
193
|
}'
|
|
196
194
|
nextmv cloud batch create --app-id hare-app --batch-experiment-id lettuce-routes \\
|
|
197
195
|
--name "Lettuce Delivery Optimization" --input-set-id veggie-gardens \\
|
|
198
|
-
--runs "$RUN1" --runs "$RUN2"[/
|
|
196
|
+
--runs "$RUN1" --runs "$RUN2"[/dim]
|
|
199
197
|
|
|
200
198
|
- Create with multiple runs in a single [magenta]json[/magenta] array.
|
|
201
|
-
$ [
|
|
199
|
+
$ [dim]RUNS='[
|
|
202
200
|
{
|
|
203
201
|
"input_id": "warren-zone-a",
|
|
204
202
|
"instance_id": "burrow-builder"
|
|
@@ -209,28 +207,28 @@ def create(
|
|
|
209
207
|
}
|
|
210
208
|
]'
|
|
211
209
|
nextmv cloud batch create --app-id hare-app --batch-experiment-id warren-expansion \\
|
|
212
|
-
--name "Warren Construction Plans" --input-set-id burrow-sites --runs "$RUNS"[/
|
|
210
|
+
--name "Warren Construction Plans" --input-set-id burrow-sites --runs "$RUNS"[/dim]
|
|
213
211
|
|
|
214
212
|
- Create a batch experiment and wait for it to complete.
|
|
215
|
-
$ [
|
|
213
|
+
$ [dim]RUN='{
|
|
216
214
|
"input_id": "carrot-harvest",
|
|
217
215
|
"instance_id": "foraging-route"
|
|
218
216
|
}'
|
|
219
217
|
nextmv cloud batch create --app-id hare-app --batch-experiment-id harvest-time \\
|
|
220
218
|
--name "Autumn Carrot Collection" --input-set-id harvest-season \\
|
|
221
|
-
--runs "$RUN" --wait[/
|
|
219
|
+
--runs "$RUN" --wait[/dim]
|
|
222
220
|
|
|
223
221
|
- Create a batch experiment and save the results to a file, waiting for completion.
|
|
224
|
-
$ [
|
|
222
|
+
$ [dim]RUN='{
|
|
225
223
|
"input_id": "predator-zones",
|
|
226
224
|
"instance_id": "safe-hopper"
|
|
227
225
|
}'
|
|
228
226
|
nextmv cloud batch create --app-id hare-app --batch-experiment-id safety-analysis \\
|
|
229
227
|
--name "Fox Avoidance Routes" --input-set-id danger-zones \\
|
|
230
|
-
--runs "$RUN" --output bunny-safety-results.json[/
|
|
228
|
+
--runs "$RUN" --output bunny-safety-results.json[/dim]
|
|
231
229
|
|
|
232
230
|
- Create a batch experiment with option sets.
|
|
233
|
-
$ [
|
|
231
|
+
$ [dim]RUN1='{
|
|
234
232
|
"input_id": "garden-route-1",
|
|
235
233
|
"instance_id": "hop-optimizer",
|
|
236
234
|
"option_set": "fast-hops"
|
|
@@ -246,7 +244,7 @@ def create(
|
|
|
246
244
|
}'
|
|
247
245
|
nextmv cloud batch create --app-id hare-app --batch-experiment-id hop-comparison \\
|
|
248
246
|
--name "Speed vs Safety Analysis" --input-set-id garden-paths \\
|
|
249
|
-
--runs "$RUN1" --runs "$RUN2" --option-sets "$OPTION_SETS"[/
|
|
247
|
+
--runs "$RUN1" --runs "$RUN2" --option-sets "$OPTION_SETS"[/dim]
|
|
250
248
|
"""
|
|
251
249
|
|
|
252
250
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
nextmv/cli/cloud/batch/delete.py
CHANGED
|
@@ -5,9 +5,9 @@ This module defines the cloud batch delete command for the Nextmv CLI.
|
|
|
5
5
|
from typing import Annotated
|
|
6
6
|
|
|
7
7
|
import typer
|
|
8
|
-
from rich.prompt import Confirm
|
|
9
8
|
|
|
10
9
|
from nextmv.cli.configuration.config import build_app
|
|
10
|
+
from nextmv.cli.confirm import get_confirmation
|
|
11
11
|
from nextmv.cli.message import info, success
|
|
12
12
|
from nextmv.cli.options import AppIDOption, BatchExperimentIDOption, ProfileOption
|
|
13
13
|
|
|
@@ -33,24 +33,23 @@ def delete(
|
|
|
33
33
|
Deletes a Nextmv Cloud batch experiment.
|
|
34
34
|
|
|
35
35
|
This action is permanent and cannot be undone. The batch experiment and all
|
|
36
|
-
associated data, including runs, will be deleted. Use the
|
|
36
|
+
associated data, including runs, will be deleted. Use the --yes
|
|
37
37
|
flag to skip the confirmation prompt.
|
|
38
38
|
|
|
39
39
|
[bold][underline]Examples[/underline][/bold]
|
|
40
40
|
|
|
41
41
|
- Delete the batch experiment with the ID [magenta]hop-analysis[/magenta] from application
|
|
42
42
|
[magenta]hare-app[/magenta].
|
|
43
|
-
$ [
|
|
43
|
+
$ [dim]nextmv cloud batch delete --app-id hare-app --batch-experiment-id hop-analysis[/dim]
|
|
44
44
|
|
|
45
45
|
- Delete the batch experiment without confirmation prompt.
|
|
46
|
-
$ [
|
|
46
|
+
$ [dim]nextmv cloud batch delete --app-id hare-app --batch-experiment-id carrot-routes --yes[/dim]
|
|
47
47
|
"""
|
|
48
48
|
|
|
49
49
|
if not yes:
|
|
50
|
-
confirm =
|
|
50
|
+
confirm = get_confirmation(
|
|
51
51
|
f"Are you sure you want to delete batch experiment [magenta]{batch_experiment_id}[/magenta] "
|
|
52
52
|
f"from application [magenta]{app_id}[/magenta]? This action cannot be undone.",
|
|
53
|
-
default=False,
|
|
54
53
|
)
|
|
55
54
|
|
|
56
55
|
if not confirm:
|
nextmv/cli/cloud/batch/get.py
CHANGED
|
@@ -42,7 +42,7 @@ def get(
|
|
|
42
42
|
"--wait",
|
|
43
43
|
"-w",
|
|
44
44
|
help="Wait for the batch experiment to complete. Results are printed to [magenta]stdout[/magenta]. "
|
|
45
|
-
"Specify output location with
|
|
45
|
+
"Specify output location with --output.",
|
|
46
46
|
),
|
|
47
47
|
] = False,
|
|
48
48
|
profile: ProfileOption = None,
|
|
@@ -50,8 +50,8 @@ def get(
|
|
|
50
50
|
"""
|
|
51
51
|
Get a Nextmv Cloud batch experiment, including its runs.
|
|
52
52
|
|
|
53
|
-
Use the
|
|
54
|
-
complete, polling for results. Using the
|
|
53
|
+
Use the --wait flag to wait for the batch experiment to
|
|
54
|
+
complete, polling for results. Using the --output flag will
|
|
55
55
|
also activate waiting, and allows you to specify a destination file for the
|
|
56
56
|
results.
|
|
57
57
|
|
|
@@ -59,17 +59,17 @@ def get(
|
|
|
59
59
|
|
|
60
60
|
- Get the batch experiment with ID [magenta]carrot-optimization[/magenta] from application
|
|
61
61
|
[magenta]hare-app[/magenta].
|
|
62
|
-
$ [
|
|
62
|
+
$ [dim]nextmv cloud batch get --app-id hare-app --batch-experiment-id carrot-optimization[/dim]
|
|
63
63
|
|
|
64
64
|
- Get the batch experiment and wait for it to complete if necessary.
|
|
65
|
-
$ [
|
|
65
|
+
$ [dim]nextmv cloud batch get --app-id hare-app --batch-experiment-id bunny-hop-test --wait[/dim]
|
|
66
66
|
|
|
67
67
|
- Get the batch experiment and save the results to a file.
|
|
68
|
-
$ [
|
|
69
|
-
--output results.json[/
|
|
68
|
+
$ [dim]nextmv cloud batch get --app-id hare-app --batch-experiment-id warren-planning \\
|
|
69
|
+
--output results.json[/dim]
|
|
70
70
|
|
|
71
71
|
- Get the batch experiment using a specific profile.
|
|
72
|
-
$ [
|
|
72
|
+
$ [dim]nextmv cloud batch get --app-id hare-app --batch-experiment-id lettuce-routes --profile prod[/dim]
|
|
73
73
|
"""
|
|
74
74
|
|
|
75
75
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
nextmv/cli/cloud/batch/list.py
CHANGED
|
@@ -38,13 +38,13 @@ def list(
|
|
|
38
38
|
[bold][underline]Examples[/underline][/bold]
|
|
39
39
|
|
|
40
40
|
- List all batch experiments for application [magenta]hare-app[/magenta].
|
|
41
|
-
$ [
|
|
41
|
+
$ [dim]nextmv cloud batch list --app-id hare-app[/dim]
|
|
42
42
|
|
|
43
43
|
- List all batch experiments and save to a file.
|
|
44
|
-
$ [
|
|
44
|
+
$ [dim]nextmv cloud batch list --app-id hare-app --output experiments.json[/dim]
|
|
45
45
|
|
|
46
46
|
- List all batch experiments using a specific profile.
|
|
47
|
-
$ [
|
|
47
|
+
$ [dim]nextmv cloud batch list --app-id hare-app --profile prod[/dim]
|
|
48
48
|
"""
|
|
49
49
|
|
|
50
50
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
@@ -41,14 +41,14 @@ def metadata(
|
|
|
41
41
|
|
|
42
42
|
- Get metadata for batch experiment [magenta]bunny-warren-optimization[/magenta] from application
|
|
43
43
|
[magenta]hare-app[/magenta].
|
|
44
|
-
$ [
|
|
44
|
+
$ [dim]nextmv cloud batch metadata --app-id hare-app --batch-experiment-id bunny-warren-optimization[/dim]
|
|
45
45
|
|
|
46
46
|
- Get metadata and save to a file.
|
|
47
|
-
$ [
|
|
48
|
-
--output metadata.json[/
|
|
47
|
+
$ [dim]nextmv cloud batch metadata --app-id hare-app --batch-experiment-id lettuce-delivery \\
|
|
48
|
+
--output metadata.json[/dim]
|
|
49
49
|
|
|
50
50
|
- Get metadata using a specific profile.
|
|
51
|
-
$ [
|
|
51
|
+
$ [dim]nextmv cloud batch metadata --app-id hare-app --batch-experiment-id hop-schedule --profile prod[/dim]
|
|
52
52
|
"""
|
|
53
53
|
|
|
54
54
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
nextmv/cli/cloud/batch/update.py
CHANGED
|
@@ -57,17 +57,17 @@ def update(
|
|
|
57
57
|
[bold][underline]Examples[/underline][/bold]
|
|
58
58
|
|
|
59
59
|
- Update the name of a batch experiment.
|
|
60
|
-
$ [
|
|
61
|
-
--name "Spring Carrot Harvest"[/
|
|
60
|
+
$ [dim]nextmv cloud batch update --app-id hare-app --batch-experiment-id carrot-feast \\
|
|
61
|
+
--name "Spring Carrot Harvest"[/dim]
|
|
62
62
|
|
|
63
63
|
- Update the description of a batch experiment.
|
|
64
|
-
$ [
|
|
65
|
-
--description "Optimizing hop paths through the meadow"[/
|
|
64
|
+
$ [dim]nextmv cloud batch update --app-id hare-app --batch-experiment-id bunny-hop-routes \\
|
|
65
|
+
--description "Optimizing hop paths through the meadow"[/dim]
|
|
66
66
|
|
|
67
67
|
- Update both name and description and save the result.
|
|
68
|
-
$ [
|
|
68
|
+
$ [dim]nextmv cloud batch update --app-id hare-app --batch-experiment-id lettuce-delivery \\
|
|
69
69
|
--name "Warren Lettuce Express" --description "Fast lettuce delivery to all burrows" \\
|
|
70
|
-
--output updated-batch.json[/
|
|
70
|
+
--output updated-batch.json[/dim]
|
|
71
71
|
"""
|
|
72
72
|
|
|
73
73
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
@@ -14,7 +14,7 @@ app.add_typer(upload_app)
|
|
|
14
14
|
@app.callback()
|
|
15
15
|
def callback() -> None:
|
|
16
16
|
"""
|
|
17
|
-
Upload data for Nextmv Cloud application
|
|
17
|
+
Upload data for Nextmv Cloud application components.
|
|
18
18
|
|
|
19
19
|
When data is too large (exceeds [magenta]5 MiB[/magenta]), or you are
|
|
20
20
|
working with the [magenta]multi-file[/magenta] content format, you can use
|
nextmv/cli/cloud/data/upload.py
CHANGED
|
@@ -45,29 +45,29 @@ def upload(
|
|
|
45
45
|
profile: ProfileOption = None,
|
|
46
46
|
) -> None:
|
|
47
47
|
"""
|
|
48
|
-
Upload data for Nextmv Cloud application
|
|
48
|
+
Upload data for Nextmv Cloud application components.
|
|
49
49
|
|
|
50
50
|
When data is too large, or is not in a text-based content format, you can
|
|
51
51
|
use this command to upload information for a Nextmv Cloud application. Data
|
|
52
52
|
is used for starting new runs, tracking runs, performing experiments, and
|
|
53
53
|
more.
|
|
54
54
|
|
|
55
|
-
The
|
|
55
|
+
The --upload-url flag is required to specify the pre-signed
|
|
56
56
|
upload URL. It can be obtained using the [code]nextmv cloud upload
|
|
57
57
|
create[/code] command. Use the [magenta].upload_url[/magenta] field from
|
|
58
58
|
the command output.
|
|
59
59
|
|
|
60
60
|
The data input should be given through [magenta]stdin[/magenta] or the
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
--input flag. When using the --input flag, the value can be one of the
|
|
62
|
+
following:
|
|
63
63
|
|
|
64
|
-
- [
|
|
64
|
+
- [yellow]<FILE_PATH>[/yellow]: path to a [magenta]file[/magenta] containing
|
|
65
65
|
the data. Use with the [magenta]json[/magenta], and
|
|
66
66
|
[magenta]text[/magenta] content formats.
|
|
67
|
-
- [
|
|
67
|
+
- [yellow]<DIR_PATH>[/yellow]: path to a [magenta]directory[/magenta]
|
|
68
68
|
containing data files. Use with the [magenta]multi-file[/magenta]
|
|
69
69
|
content format.
|
|
70
|
-
- [
|
|
70
|
+
- [yellow]<.tar.gz PATH>[/yellow]: path to a [magenta].tar.gz[/magenta] file
|
|
71
71
|
containing tarred data files. Use with the [magenta]multi-file[/magenta]
|
|
72
72
|
content format.
|
|
73
73
|
|
|
@@ -75,30 +75,30 @@ def upload(
|
|
|
75
75
|
|
|
76
76
|
- Upload data from [magenta]stdin[/magenta] for application
|
|
77
77
|
[magenta]hare-app[/magenta].
|
|
78
|
-
$ [
|
|
78
|
+
$ [dim]echo '{"key": "value"}' | nextmv cloud data upload --app-id hare-app --upload-url <URL>[/dim]
|
|
79
79
|
|
|
80
80
|
- Upload data from a [magenta]JSON[/magenta] file.
|
|
81
|
-
$ [
|
|
81
|
+
$ [dim]nextmv cloud data upload --app-id hare-app --upload-url <URL> --input data.json[/dim]
|
|
82
82
|
|
|
83
83
|
- Upload data from a [magenta]text[/magenta] file.
|
|
84
|
-
$ [
|
|
84
|
+
$ [dim]nextmv cloud data upload --app-id hare-app --upload-url <URL> --input data.txt[/dim]
|
|
85
85
|
|
|
86
86
|
- Upload [magenta]multi-file[/magenta] data from a directory.
|
|
87
|
-
$ [
|
|
87
|
+
$ [dim]nextmv cloud data upload --app-id hare-app --upload-url <URL> --input ./data_directory[/dim]
|
|
88
88
|
|
|
89
89
|
- Upload [magenta]multi-file[/magenta] data from a
|
|
90
90
|
[magenta].tar.gz[/magenta] file.
|
|
91
|
-
$ [
|
|
91
|
+
$ [dim]nextmv cloud data upload --app-id hare-app --upload-url <URL> --input data.tar.gz[/dim]
|
|
92
92
|
|
|
93
93
|
- Upload data using a specific profile.
|
|
94
|
-
$ [
|
|
95
|
-
--profile production[/
|
|
94
|
+
$ [dim]nextmv cloud data upload --app-id hare-app --upload-url <URL> --input data.json \\
|
|
95
|
+
--profile production[/dim]
|
|
96
96
|
"""
|
|
97
97
|
|
|
98
98
|
# Validate that input is provided.
|
|
99
99
|
stdin = sys.stdin.read().strip() if sys.stdin.isatty() is False else None
|
|
100
100
|
if stdin is None and (input is None or input == ""):
|
|
101
|
-
error("Input data must be provided via the
|
|
101
|
+
error("Input data must be provided via the --input flag or [magenta]stdin[/magenta].")
|
|
102
102
|
|
|
103
103
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
104
104
|
data_kwarg = resolve_data_kwarg(
|
|
@@ -7,6 +7,7 @@ import typer
|
|
|
7
7
|
from nextmv.cli.cloud.ensemble.create import app as create_app
|
|
8
8
|
from nextmv.cli.cloud.ensemble.delete import app as delete_app
|
|
9
9
|
from nextmv.cli.cloud.ensemble.get import app as get_app
|
|
10
|
+
from nextmv.cli.cloud.ensemble.list import app as list_app
|
|
10
11
|
from nextmv.cli.cloud.ensemble.update import app as update_app
|
|
11
12
|
|
|
12
13
|
# Set up subcommand application.
|
|
@@ -14,6 +15,7 @@ app = typer.Typer()
|
|
|
14
15
|
app.add_typer(create_app)
|
|
15
16
|
app.add_typer(delete_app)
|
|
16
17
|
app.add_typer(get_app)
|
|
18
|
+
app.add_typer(list_app)
|
|
17
19
|
app.add_typer(update_app)
|
|
18
20
|
|
|
19
21
|
|
|
@@ -30,13 +30,12 @@ app = typer.Typer()
|
|
|
30
30
|
[bold][underline]Run Groups[/underline][/bold]
|
|
31
31
|
|
|
32
32
|
Run groups are provided as [magenta]json[/magenta] objects using the
|
|
33
|
-
|
|
34
|
-
are executed.
|
|
33
|
+
--run-groups flag. Each run group specifies how child runs are executed.
|
|
35
34
|
|
|
36
35
|
You can provide run groups in three ways:
|
|
37
36
|
- A single run group as a [magenta]json[/magenta] object.
|
|
38
|
-
- Multiple run groups by repeating the
|
|
39
|
-
- Multiple run groups as a [magenta]json[/magenta] array in a single
|
|
37
|
+
- Multiple run groups by repeating the --run-groups flag.
|
|
38
|
+
- Multiple run groups as a [magenta]json[/magenta] array in a single --run-groups flag.
|
|
40
39
|
|
|
41
40
|
Each run group must have the following fields:
|
|
42
41
|
- [magenta]id[/magenta]: Unique identifier for the run group (required).
|
|
@@ -46,23 +45,23 @@ app = typer.Typer()
|
|
|
46
45
|
- [magenta]repetitions[/magenta]: Number of times to repeat the run (optional).
|
|
47
46
|
|
|
48
47
|
Object format:
|
|
49
|
-
[
|
|
48
|
+
[dim]{{
|
|
50
49
|
"id": "rg1",
|
|
51
50
|
"instance_id": "inst-123",
|
|
52
51
|
"options": {{"param": "value"}},
|
|
53
52
|
"repetitions": 5
|
|
54
|
-
}}[/
|
|
53
|
+
}}[/dim]
|
|
55
54
|
|
|
56
55
|
[bold][underline]Evaluation Rules[/underline][/bold]
|
|
57
56
|
|
|
58
57
|
Evaluation rules are provided as [magenta]json[/magenta] objects using the
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
--rules flag. Each rule determines how to evaluate and select the best
|
|
59
|
+
result from the child runs.
|
|
61
60
|
|
|
62
61
|
You can provide rules in three ways:
|
|
63
62
|
- A single rule as a [magenta]json[/magenta] object.
|
|
64
|
-
- Multiple rules by repeating the
|
|
65
|
-
- Multiple rules as a [magenta]json[/magenta] array in a single
|
|
63
|
+
- Multiple rules by repeating the --rules flag.
|
|
64
|
+
- Multiple rules as a [magenta]json[/magenta] array in a single --rules flag.
|
|
66
65
|
|
|
67
66
|
Each rule must have the following fields:
|
|
68
67
|
- [magenta]id[/magenta]: Unique identifier for the rule (required).
|
|
@@ -75,18 +74,18 @@ app = typer.Typer()
|
|
|
75
74
|
- [magenta]index[/magenta]: Evaluation order - lower indices evaluated first (required).
|
|
76
75
|
|
|
77
76
|
Object format:
|
|
78
|
-
[
|
|
77
|
+
[dim]{{
|
|
79
78
|
"id": "rule1",
|
|
80
79
|
"statistics_path": "$.result.value",
|
|
81
80
|
"objective": "minimize",
|
|
82
81
|
"tolerance": {{"value": 0.1, "type": "relative"}},
|
|
83
82
|
"index": 0
|
|
84
|
-
}}[/
|
|
83
|
+
}}[/dim]
|
|
85
84
|
|
|
86
85
|
[bold][underline]Examples[/underline][/bold]
|
|
87
86
|
|
|
88
87
|
- Create an ensemble definition with a single run group and rule.
|
|
89
|
-
$ [
|
|
88
|
+
$ [dim]RUN_GROUP='{{
|
|
90
89
|
"id": "rg1",
|
|
91
90
|
"instance_id": "inst-123"
|
|
92
91
|
}}'
|
|
@@ -97,10 +96,10 @@ app = typer.Typer()
|
|
|
97
96
|
"tolerance": {{"value": 0.1, "type": "relative"}},
|
|
98
97
|
"index": 0
|
|
99
98
|
}}'
|
|
100
|
-
nextmv cloud ensemble create --app-id hare-app --run-groups "$RUN_GROUP" --rules "$RULE"[/
|
|
99
|
+
nextmv cloud ensemble create --app-id hare-app --run-groups "$RUN_GROUP" --rules "$RULE"[/dim]
|
|
101
100
|
|
|
102
101
|
- Create with multiple run groups by repeating the flag.
|
|
103
|
-
$ [
|
|
102
|
+
$ [dim]RUN_GROUP_1='{{
|
|
104
103
|
"id": "rg1",
|
|
105
104
|
"instance_id": "inst-123"
|
|
106
105
|
}}'
|
|
@@ -117,10 +116,10 @@ app = typer.Typer()
|
|
|
117
116
|
"index": 0
|
|
118
117
|
}}'
|
|
119
118
|
nextmv cloud ensemble create --app-id hare-app --run-groups "$RUN_GROUP_1" --run-groups "$RUN_GROUP_2" \\
|
|
120
|
-
--rules "$RULE"[/
|
|
119
|
+
--rules "$RULE"[/dim]
|
|
121
120
|
|
|
122
121
|
- Create with multiple items in a single JSON array.
|
|
123
|
-
$ [
|
|
122
|
+
$ [dim]RUN_GROUPS='[
|
|
124
123
|
{{"id": "rg1", "instance_id": "inst-123"}},
|
|
125
124
|
{{"id": "rg2", "instance_id": "inst-456"}}
|
|
126
125
|
]'
|
|
@@ -131,10 +130,10 @@ app = typer.Typer()
|
|
|
131
130
|
"tolerance": {{"value": 0.1, "type": "relative"}},
|
|
132
131
|
"index": 0
|
|
133
132
|
}}]'
|
|
134
|
-
nextmv cloud ensemble create --app-id hare-app --run-groups "$RUN_GROUPS" --rules "$RULES"[/
|
|
133
|
+
nextmv cloud ensemble create --app-id hare-app --run-groups "$RUN_GROUPS" --rules "$RULES"[/dim]
|
|
135
134
|
|
|
136
135
|
- Create with custom ID, name, and description.
|
|
137
|
-
$ [
|
|
136
|
+
$ [dim]RUN_GROUP='{{
|
|
138
137
|
"id": "rg1",
|
|
139
138
|
"instance_id": "inst-123"
|
|
140
139
|
}}'
|
|
@@ -148,10 +147,10 @@ app = typer.Typer()
|
|
|
148
147
|
nextmv cloud ensemble create --app-id hare-app \\
|
|
149
148
|
--ensemble-definition-id prod-ensemble --name "Production Ensemble" \\
|
|
150
149
|
--description "Production ensemble with multiple solvers" \\
|
|
151
|
-
--run-groups "$RUN_GROUP" --rules "$RULE"[/
|
|
150
|
+
--run-groups "$RUN_GROUP" --rules "$RULE"[/dim]
|
|
152
151
|
|
|
153
152
|
- Create with run group repetitions.
|
|
154
|
-
$ [
|
|
153
|
+
$ [dim]RUN_GROUP='{{
|
|
155
154
|
"id": "rg1",
|
|
156
155
|
"instance_id": "inst-123",
|
|
157
156
|
"repetitions": 5
|
|
@@ -163,7 +162,7 @@ app = typer.Typer()
|
|
|
163
162
|
"tolerance": {{"value": 0.1, "type": "relative"}},
|
|
164
163
|
"index": 0
|
|
165
164
|
}}'
|
|
166
|
-
nextmv cloud ensemble create --app-id hare-app --run-groups "$RUN_GROUP" --rules "$RULE"[/
|
|
165
|
+
nextmv cloud ensemble create --app-id hare-app --run-groups "$RUN_GROUP" --rules "$RULE"[/dim]
|
|
167
166
|
"""
|
|
168
167
|
)
|
|
169
168
|
def create(
|
|
@@ -5,9 +5,9 @@ This module defines the cloud ensemble delete command for the Nextmv CLI.
|
|
|
5
5
|
from typing import Annotated
|
|
6
6
|
|
|
7
7
|
import typer
|
|
8
|
-
from rich.prompt import Confirm
|
|
9
8
|
|
|
10
9
|
from nextmv.cli.configuration.config import build_app
|
|
10
|
+
from nextmv.cli.confirm import get_confirmation
|
|
11
11
|
from nextmv.cli.message import info, success
|
|
12
12
|
from nextmv.cli.options import AppIDOption, EnsembleDefinitionIDOption, ProfileOption
|
|
13
13
|
|
|
@@ -32,24 +32,23 @@ def delete(
|
|
|
32
32
|
"""
|
|
33
33
|
Deletes a Nextmv Cloud ensemble definition.
|
|
34
34
|
|
|
35
|
-
This action is permanent and cannot be undone. Use the
|
|
35
|
+
This action is permanent and cannot be undone. Use the --yes
|
|
36
36
|
flag to skip the confirmation prompt.
|
|
37
37
|
|
|
38
38
|
[bold][underline]Examples[/underline][/bold]
|
|
39
39
|
|
|
40
40
|
- Delete the ensemble definition with the ID [magenta]prod-ensemble[/magenta] from application
|
|
41
41
|
[magenta]hare-app[/magenta].
|
|
42
|
-
$ [
|
|
42
|
+
$ [dim]nextmv cloud ensemble delete --app-id hare-app --ensemble-definition-id prod-ensemble[/dim]
|
|
43
43
|
|
|
44
44
|
- Delete the ensemble definition without confirmation prompt.
|
|
45
|
-
$ [
|
|
45
|
+
$ [dim]nextmv cloud ensemble delete --app-id hare-app --ensemble-definition-id prod-ensemble --yes[/dim]
|
|
46
46
|
"""
|
|
47
47
|
|
|
48
48
|
if not yes:
|
|
49
|
-
confirm =
|
|
49
|
+
confirm = get_confirmation(
|
|
50
50
|
f"Are you sure you want to delete ensemble definition [magenta]{ensemble_definition_id}[/magenta] "
|
|
51
51
|
f"from application [magenta]{app_id}[/magenta]? This action cannot be undone.",
|
|
52
|
-
default=False,
|
|
53
52
|
)
|
|
54
53
|
|
|
55
54
|
if not confirm:
|
nextmv/cli/cloud/ensemble/get.py
CHANGED
|
@@ -40,13 +40,13 @@ def get(
|
|
|
40
40
|
|
|
41
41
|
- Get the ensemble definition with the ID [magenta]prod-ensemble[/magenta] from
|
|
42
42
|
application [magenta]hare-app[/magenta].
|
|
43
|
-
$ [
|
|
44
|
-
--ensemble-definition-id prod-ensemble[/
|
|
43
|
+
$ [dim]nextmv cloud ensemble get --app-id hare-app \\
|
|
44
|
+
--ensemble-definition-id prod-ensemble[/dim]
|
|
45
45
|
|
|
46
46
|
- Get the ensemble definition with the ID [magenta]prod-ensemble[/magenta] and
|
|
47
47
|
save the information to an [magenta]ensemble.json[/magenta] file.
|
|
48
|
-
$ [
|
|
49
|
-
--ensemble-definition-id prod-ensemble --output ensemble.json[/
|
|
48
|
+
$ [dim]nextmv cloud ensemble get --app-id hare-app \\
|
|
49
|
+
--ensemble-definition-id prod-ensemble --output ensemble.json[/dim]
|
|
50
50
|
"""
|
|
51
51
|
|
|
52
52
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module defines the cloud ensemble list command for the Nextmv CLI.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from typing import Annotated
|
|
7
|
+
|
|
8
|
+
import typer
|
|
9
|
+
|
|
10
|
+
from nextmv.cli.configuration.config import build_app
|
|
11
|
+
from nextmv.cli.message import in_progress, print_json, success
|
|
12
|
+
from nextmv.cli.options import AppIDOption, ProfileOption
|
|
13
|
+
|
|
14
|
+
# Set up subcommand application.
|
|
15
|
+
app = typer.Typer()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@app.command()
|
|
19
|
+
def list(
|
|
20
|
+
app_id: AppIDOption,
|
|
21
|
+
output: Annotated[
|
|
22
|
+
str | None,
|
|
23
|
+
typer.Option(
|
|
24
|
+
"--output",
|
|
25
|
+
"-o",
|
|
26
|
+
help="Saves the list of ensemble definitions to this location.",
|
|
27
|
+
metavar="OUTPUT_PATH",
|
|
28
|
+
),
|
|
29
|
+
] = None,
|
|
30
|
+
profile: ProfileOption = None,
|
|
31
|
+
) -> None:
|
|
32
|
+
"""
|
|
33
|
+
List all Nextmv Cloud ensemble definitions for an application.
|
|
34
|
+
|
|
35
|
+
This command retrieves all ensemble definitions associated with the specified
|
|
36
|
+
application.
|
|
37
|
+
|
|
38
|
+
[bold][underline]Examples[/underline][/bold]
|
|
39
|
+
|
|
40
|
+
- List all ensemble definitions for application [magenta]hare-app[/magenta].
|
|
41
|
+
$ [dim]nextmv cloud ensemble list --app-id hare-app[/dim]
|
|
42
|
+
|
|
43
|
+
- List all ensemble definitions and save to a file.
|
|
44
|
+
$ [dim]nextmv cloud ensemble list --app-id hare-app --output ensembles.json[/dim]
|
|
45
|
+
|
|
46
|
+
- List all ensemble definitions using a specific profile.
|
|
47
|
+
$ [dim]nextmv cloud ensemble list --app-id hare-app --profile prod[/dim]
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
51
|
+
in_progress(msg="Listing ensemble definitions...")
|
|
52
|
+
ensembles = cloud_app.list_ensemble_definitions()
|
|
53
|
+
ensembles_dict = [ensemble.to_dict() for ensemble in ensembles]
|
|
54
|
+
|
|
55
|
+
if output is not None and output != "":
|
|
56
|
+
with open(output, "w") as f:
|
|
57
|
+
json.dump(ensembles_dict, f, indent=2)
|
|
58
|
+
|
|
59
|
+
success(msg=f"Ensemble definitions list saved to [magenta]{output}[/magenta].")
|
|
60
|
+
|
|
61
|
+
return
|
|
62
|
+
|
|
63
|
+
print_json(ensembles_dict)
|