nextmv 1.0.0__py3-none-any.whl → 1.0.0.dev0__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/__entrypoint__.py +2 -1
- nextmv/__init__.py +4 -0
- nextmv/cli/CONTRIBUTING.md +40 -112
- nextmv/cli/cloud/__init__.py +0 -4
- nextmv/cli/cloud/acceptance/create.py +22 -20
- nextmv/cli/cloud/acceptance/delete.py +12 -8
- nextmv/cli/cloud/acceptance/get.py +10 -9
- 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 +8 -7
- nextmv/cli/cloud/account/get.py +3 -3
- nextmv/cli/cloud/account/update.py +5 -5
- nextmv/cli/cloud/app/create.py +26 -25
- nextmv/cli/cloud/app/delete.py +7 -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 +54 -349
- nextmv/cli/cloud/app/update.py +12 -12
- nextmv/cli/cloud/batch/create.py +28 -26
- nextmv/cli/cloud/batch/delete.py +10 -6
- nextmv/cli/cloud/batch/get.py +9 -9
- 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 +0 -2
- nextmv/cli/cloud/ensemble/create.py +22 -21
- nextmv/cli/cloud/ensemble/delete.py +10 -6
- nextmv/cli/cloud/ensemble/get.py +4 -4
- nextmv/cli/cloud/ensemble/update.py +9 -9
- nextmv/cli/cloud/input_set/__init__.py +0 -2
- nextmv/cli/cloud/input_set/create.py +22 -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 +15 -14
- nextmv/cli/cloud/instance/delete.py +7 -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 +16 -14
- nextmv/cli/cloud/managed_input/delete.py +8 -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 +40 -34
- 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 +10 -9
- nextmv/cli/cloud/run/metadata.py +4 -4
- nextmv/cli/cloud/run/track.py +33 -32
- nextmv/cli/cloud/scenario/create.py +21 -21
- nextmv/cli/cloud/scenario/delete.py +10 -6
- nextmv/cli/cloud/scenario/get.py +9 -9
- 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 +10 -6
- nextmv/cli/cloud/secrets/get.py +4 -4
- nextmv/cli/cloud/secrets/list.py +3 -3
- nextmv/cli/cloud/secrets/update.py +20 -17
- nextmv/cli/cloud/upload/create.py +2 -2
- nextmv/cli/cloud/version/create.py +10 -9
- nextmv/cli/cloud/version/delete.py +7 -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/__init__.py +1 -1
- nextmv/cli/community/clone.py +204 -20
- nextmv/cli/community/list.py +125 -60
- nextmv/cli/configuration/config.py +10 -43
- nextmv/cli/configuration/create.py +7 -7
- nextmv/cli/configuration/delete.py +8 -8
- nextmv/cli/configuration/list.py +3 -3
- nextmv/cli/main.py +36 -26
- nextmv/cli/message.py +54 -71
- nextmv/cli/options.py +0 -28
- nextmv/cli/version.py +1 -1
- nextmv/cloud/__init__.py +38 -14
- nextmv/cloud/acceptance_test.py +65 -1
- nextmv/cloud/account.py +6 -1
- nextmv/cloud/application/__init__.py +75 -18
- nextmv/cloud/application/_acceptance.py +8 -13
- nextmv/cloud/application/_batch_scenario.py +19 -4
- nextmv/cloud/application/_input_set.py +6 -42
- nextmv/cloud/application/_instance.py +3 -3
- nextmv/cloud/application/_managed_input.py +2 -2
- nextmv/cloud/application/_version.py +3 -4
- nextmv/cloud/batch_experiment.py +1 -3
- nextmv/cloud/integration.py +4 -7
- nextmv/deprecated.py +3 -5
- nextmv/input.py +52 -0
- nextmv/local/runner.py +1 -1
- nextmv/model.py +11 -50
- nextmv/options.py +256 -11
- nextmv/output.py +62 -0
- nextmv/run.py +10 -1
- nextmv/status.py +51 -1
- {nextmv-1.0.0.dist-info → nextmv-1.0.0.dev0.dist-info}/METADATA +4 -5
- nextmv-1.0.0.dev0.dist-info/RECORD +158 -0
- nextmv/cli/cloud/ensemble/list.py +0 -63
- nextmv/cli/cloud/input_set/delete.py +0 -64
- nextmv/cli/cloud/shadow/__init__.py +0 -33
- nextmv/cli/cloud/shadow/create.py +0 -184
- nextmv/cli/cloud/shadow/delete.py +0 -64
- nextmv/cli/cloud/shadow/get.py +0 -61
- nextmv/cli/cloud/shadow/list.py +0 -63
- nextmv/cli/cloud/shadow/metadata.py +0 -66
- nextmv/cli/cloud/shadow/start.py +0 -43
- nextmv/cli/cloud/shadow/stop.py +0 -53
- nextmv/cli/cloud/shadow/update.py +0 -96
- nextmv/cli/cloud/switchback/__init__.py +0 -33
- nextmv/cli/cloud/switchback/create.py +0 -151
- nextmv/cli/cloud/switchback/delete.py +0 -64
- nextmv/cli/cloud/switchback/get.py +0 -62
- nextmv/cli/cloud/switchback/list.py +0 -63
- nextmv/cli/cloud/switchback/metadata.py +0 -68
- nextmv/cli/cloud/switchback/start.py +0 -43
- nextmv/cli/cloud/switchback/stop.py +0 -53
- nextmv/cli/cloud/switchback/update.py +0 -96
- nextmv/cli/confirm.py +0 -34
- nextmv/cloud/application/_shadow.py +0 -320
- nextmv/cloud/application/_switchback.py +0 -332
- nextmv/cloud/community.py +0 -446
- nextmv/cloud/shadow.py +0 -254
- nextmv/cloud/switchback.py +0 -228
- nextmv-1.0.0.dist-info/RECORD +0 -185
- nextmv-1.0.0.dist-info/entry_points.txt +0 -2
- {nextmv-1.0.0.dist-info → nextmv-1.0.0.dev0.dist-info}/WHEEL +0 -0
- {nextmv-1.0.0.dist-info → nextmv-1.0.0.dev0.dist-info}/licenses/LICENSE +0 -0
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
|
|
8
9
|
|
|
9
10
|
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,27 +33,31 @@ 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 --yes
|
|
36
|
+
associated data, including runs, will be deleted. Use the [code]--yes[/code]
|
|
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
|
+
$ [green]nextmv cloud batch delete --app-id hare-app --batch-experiment-id hop-analysis[/green]
|
|
44
44
|
|
|
45
45
|
- Delete the batch experiment without confirmation prompt.
|
|
46
|
-
$ [
|
|
46
|
+
$ [green]nextmv cloud batch delete --app-id hare-app --batch-experiment-id carrot-routes --yes[/green]
|
|
47
47
|
"""
|
|
48
48
|
|
|
49
49
|
if not yes:
|
|
50
|
-
confirm =
|
|
50
|
+
confirm = Confirm.ask(
|
|
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,
|
|
53
54
|
)
|
|
54
55
|
|
|
55
56
|
if not confirm:
|
|
56
|
-
info(
|
|
57
|
+
info(
|
|
58
|
+
msg=f"Batch experiment [magenta]{batch_experiment_id}[/magenta] will not be deleted.",
|
|
59
|
+
emoji=":bulb:",
|
|
60
|
+
)
|
|
57
61
|
return
|
|
58
62
|
|
|
59
63
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
nextmv/cli/cloud/batch/get.py
CHANGED
|
@@ -42,16 +42,16 @@ 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 --output.",
|
|
45
|
+
"Specify output location with [code]--output[/code].",
|
|
46
46
|
),
|
|
47
47
|
] = False,
|
|
48
48
|
profile: ProfileOption = None,
|
|
49
49
|
) -> None:
|
|
50
50
|
"""
|
|
51
|
-
Get a Nextmv Cloud batch experiment
|
|
51
|
+
Get a Nextmv Cloud batch experiment.
|
|
52
52
|
|
|
53
|
-
Use the --wait flag to wait for the batch experiment to
|
|
54
|
-
complete, polling for results. Using the --output flag will
|
|
53
|
+
Use the [code]--wait[/code] flag to wait for the batch experiment to
|
|
54
|
+
complete, polling for results. Using the [code]--output[/code] 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
|
+
$ [green]nextmv cloud batch get --app-id hare-app --batch-experiment-id carrot-optimization[/green]
|
|
63
63
|
|
|
64
64
|
- Get the batch experiment and wait for it to complete if necessary.
|
|
65
|
-
$ [
|
|
65
|
+
$ [green]nextmv cloud batch get --app-id hare-app --batch-experiment-id bunny-hop-test --wait[/green]
|
|
66
66
|
|
|
67
67
|
- Get the batch experiment and save the results to a file.
|
|
68
|
-
$ [
|
|
69
|
-
--output results.json[/
|
|
68
|
+
$ [green]nextmv cloud batch get --app-id hare-app --batch-experiment-id warren-planning \\
|
|
69
|
+
--output results.json[/green]
|
|
70
70
|
|
|
71
71
|
- Get the batch experiment using a specific profile.
|
|
72
|
-
$ [
|
|
72
|
+
$ [green]nextmv cloud batch get --app-id hare-app --batch-experiment-id lettuce-routes --profile prod[/green]
|
|
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
|
+
$ [green]nextmv cloud batch list --app-id hare-app[/green]
|
|
42
42
|
|
|
43
43
|
- List all batch experiments and save to a file.
|
|
44
|
-
$ [
|
|
44
|
+
$ [green]nextmv cloud batch list --app-id hare-app --output experiments.json[/green]
|
|
45
45
|
|
|
46
46
|
- List all batch experiments using a specific profile.
|
|
47
|
-
$ [
|
|
47
|
+
$ [green]nextmv cloud batch list --app-id hare-app --profile prod[/green]
|
|
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
|
+
$ [green]nextmv cloud batch metadata --app-id hare-app --batch-experiment-id bunny-warren-optimization[/green]
|
|
45
45
|
|
|
46
46
|
- Get metadata and save to a file.
|
|
47
|
-
$ [
|
|
48
|
-
--output metadata.json[/
|
|
47
|
+
$ [green]nextmv cloud batch metadata --app-id hare-app --batch-experiment-id lettuce-delivery \\
|
|
48
|
+
--output metadata.json[/green]
|
|
49
49
|
|
|
50
50
|
- Get metadata using a specific profile.
|
|
51
|
-
$ [
|
|
51
|
+
$ [green]nextmv cloud batch metadata --app-id hare-app --batch-experiment-id hop-schedule --profile prod[/green]
|
|
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
|
+
$ [green]nextmv cloud batch update --app-id hare-app --batch-experiment-id carrot-feast \\
|
|
61
|
+
--name "Spring Carrot Harvest"[/green]
|
|
62
62
|
|
|
63
63
|
- Update the description of a batch experiment.
|
|
64
|
-
$ [
|
|
65
|
-
--description "Optimizing hop paths through the meadow"[/
|
|
64
|
+
$ [green]nextmv cloud batch update --app-id hare-app --batch-experiment-id bunny-hop-routes \\
|
|
65
|
+
--description "Optimizing hop paths through the meadow"[/green]
|
|
66
66
|
|
|
67
67
|
- Update both name and description and save the result.
|
|
68
|
-
$ [
|
|
68
|
+
$ [green]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[/green]
|
|
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 runs.
|
|
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 runs.
|
|
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 --upload-url flag is required to specify the pre-signed
|
|
55
|
+
The [code]--upload-url[/code] 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
|
-
--input flag. When using the --input flag, the
|
|
62
|
-
following:
|
|
61
|
+
[code]--input[/code] flag. When using the [code]--input[/code] flag, the
|
|
62
|
+
value can be one of the following:
|
|
63
63
|
|
|
64
|
-
- [
|
|
64
|
+
- [green]<FILE_PATH>[/green]: 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
|
+
- [green]<DIR_PATH>[/green]: path to a [magenta]directory[/magenta]
|
|
68
68
|
containing data files. Use with the [magenta]multi-file[/magenta]
|
|
69
69
|
content format.
|
|
70
|
-
- [
|
|
70
|
+
- [green]<.tar.gz_PATH>[/green]: 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
|
+
$ [green]echo '{"key": "value"}' | nextmv cloud data upload --app-id hare-app --upload-url <URL>[/green]
|
|
79
79
|
|
|
80
80
|
- Upload data from a [magenta]JSON[/magenta] file.
|
|
81
|
-
$ [
|
|
81
|
+
$ [green]nextmv cloud data upload --app-id hare-app --upload-url <URL> --input data.json[/green]
|
|
82
82
|
|
|
83
83
|
- Upload data from a [magenta]text[/magenta] file.
|
|
84
|
-
$ [
|
|
84
|
+
$ [green]nextmv cloud data upload --app-id hare-app --upload-url <URL> --input data.txt[/green]
|
|
85
85
|
|
|
86
86
|
- Upload [magenta]multi-file[/magenta] data from a directory.
|
|
87
|
-
$ [
|
|
87
|
+
$ [green]nextmv cloud data upload --app-id hare-app --upload-url <URL> --input ./data_directory[/green]
|
|
88
88
|
|
|
89
89
|
- Upload [magenta]multi-file[/magenta] data from a
|
|
90
90
|
[magenta].tar.gz[/magenta] file.
|
|
91
|
-
$ [
|
|
91
|
+
$ [green]nextmv cloud data upload --app-id hare-app --upload-url <URL> --input data.tar.gz[/green]
|
|
92
92
|
|
|
93
93
|
- Upload data using a specific profile.
|
|
94
|
-
$ [
|
|
95
|
-
--profile production[/
|
|
94
|
+
$ [green]nextmv cloud data upload --app-id hare-app --upload-url <URL> --input data.json \\
|
|
95
|
+
--profile production[/green]
|
|
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 --input flag or [magenta]stdin[/magenta].")
|
|
101
|
+
error("Input data must be provided via the [code]--input[/code] 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,7 +7,6 @@ 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
|
|
11
10
|
from nextmv.cli.cloud.ensemble.update import app as update_app
|
|
12
11
|
|
|
13
12
|
# Set up subcommand application.
|
|
@@ -15,7 +14,6 @@ app = typer.Typer()
|
|
|
15
14
|
app.add_typer(create_app)
|
|
16
15
|
app.add_typer(delete_app)
|
|
17
16
|
app.add_typer(get_app)
|
|
18
|
-
app.add_typer(list_app)
|
|
19
17
|
app.add_typer(update_app)
|
|
20
18
|
|
|
21
19
|
|
|
@@ -30,12 +30,13 @@ 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
|
-
--run-groups flag. Each run group specifies how child runs
|
|
33
|
+
[code]--run-groups[/code] flag. Each run group specifies how child runs
|
|
34
|
+
are executed.
|
|
34
35
|
|
|
35
36
|
You can provide run groups in three ways:
|
|
36
37
|
- A single run group as a [magenta]json[/magenta] object.
|
|
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.
|
|
38
|
+
- Multiple run groups by repeating the [code]--run-groups[/code] flag.
|
|
39
|
+
- Multiple run groups as a [magenta]json[/magenta] array in a single [code]--run-groups[/code] flag.
|
|
39
40
|
|
|
40
41
|
Each run group must have the following fields:
|
|
41
42
|
- [magenta]id[/magenta]: Unique identifier for the run group (required).
|
|
@@ -45,23 +46,23 @@ app = typer.Typer()
|
|
|
45
46
|
- [magenta]repetitions[/magenta]: Number of times to repeat the run (optional).
|
|
46
47
|
|
|
47
48
|
Object format:
|
|
48
|
-
[
|
|
49
|
+
[green]{{
|
|
49
50
|
"id": "rg1",
|
|
50
51
|
"instance_id": "inst-123",
|
|
51
52
|
"options": {{"param": "value"}},
|
|
52
53
|
"repetitions": 5
|
|
53
|
-
}}[/
|
|
54
|
+
}}[/green]
|
|
54
55
|
|
|
55
56
|
[bold][underline]Evaluation Rules[/underline][/bold]
|
|
56
57
|
|
|
57
58
|
Evaluation rules are provided as [magenta]json[/magenta] objects using the
|
|
58
|
-
--rules flag. Each rule determines how to evaluate and select
|
|
59
|
-
result from the child runs.
|
|
59
|
+
[code]--rules[/code] flag. Each rule determines how to evaluate and select
|
|
60
|
+
the best result from the child runs.
|
|
60
61
|
|
|
61
62
|
You can provide rules in three ways:
|
|
62
63
|
- A single rule as a [magenta]json[/magenta] object.
|
|
63
|
-
- Multiple rules by repeating the --rules flag.
|
|
64
|
-
- Multiple rules as a [magenta]json[/magenta] array in a single --rules flag.
|
|
64
|
+
- Multiple rules by repeating the [code]--rules[/code] flag.
|
|
65
|
+
- Multiple rules as a [magenta]json[/magenta] array in a single [code]--rules[/code] flag.
|
|
65
66
|
|
|
66
67
|
Each rule must have the following fields:
|
|
67
68
|
- [magenta]id[/magenta]: Unique identifier for the rule (required).
|
|
@@ -74,18 +75,18 @@ app = typer.Typer()
|
|
|
74
75
|
- [magenta]index[/magenta]: Evaluation order - lower indices evaluated first (required).
|
|
75
76
|
|
|
76
77
|
Object format:
|
|
77
|
-
[
|
|
78
|
+
[green]{{
|
|
78
79
|
"id": "rule1",
|
|
79
80
|
"statistics_path": "$.result.value",
|
|
80
81
|
"objective": "minimize",
|
|
81
82
|
"tolerance": {{"value": 0.1, "type": "relative"}},
|
|
82
83
|
"index": 0
|
|
83
|
-
}}[/
|
|
84
|
+
}}[/green]
|
|
84
85
|
|
|
85
86
|
[bold][underline]Examples[/underline][/bold]
|
|
86
87
|
|
|
87
88
|
- Create an ensemble definition with a single run group and rule.
|
|
88
|
-
$ [
|
|
89
|
+
$ [green]RUN_GROUP='{{
|
|
89
90
|
"id": "rg1",
|
|
90
91
|
"instance_id": "inst-123"
|
|
91
92
|
}}'
|
|
@@ -96,10 +97,10 @@ app = typer.Typer()
|
|
|
96
97
|
"tolerance": {{"value": 0.1, "type": "relative"}},
|
|
97
98
|
"index": 0
|
|
98
99
|
}}'
|
|
99
|
-
nextmv cloud ensemble create --app-id hare-app --run-groups "$RUN_GROUP" --rules "$RULE"[/
|
|
100
|
+
nextmv cloud ensemble create --app-id hare-app --run-groups "$RUN_GROUP" --rules "$RULE"[/green]
|
|
100
101
|
|
|
101
102
|
- Create with multiple run groups by repeating the flag.
|
|
102
|
-
$ [
|
|
103
|
+
$ [green]RUN_GROUP_1='{{
|
|
103
104
|
"id": "rg1",
|
|
104
105
|
"instance_id": "inst-123"
|
|
105
106
|
}}'
|
|
@@ -116,10 +117,10 @@ app = typer.Typer()
|
|
|
116
117
|
"index": 0
|
|
117
118
|
}}'
|
|
118
119
|
nextmv cloud ensemble create --app-id hare-app --run-groups "$RUN_GROUP_1" --run-groups "$RUN_GROUP_2" \\
|
|
119
|
-
--rules "$RULE"[/
|
|
120
|
+
--rules "$RULE"[/green]
|
|
120
121
|
|
|
121
122
|
- Create with multiple items in a single JSON array.
|
|
122
|
-
$ [
|
|
123
|
+
$ [green]RUN_GROUPS='[
|
|
123
124
|
{{"id": "rg1", "instance_id": "inst-123"}},
|
|
124
125
|
{{"id": "rg2", "instance_id": "inst-456"}}
|
|
125
126
|
]'
|
|
@@ -130,10 +131,10 @@ app = typer.Typer()
|
|
|
130
131
|
"tolerance": {{"value": 0.1, "type": "relative"}},
|
|
131
132
|
"index": 0
|
|
132
133
|
}}]'
|
|
133
|
-
nextmv cloud ensemble create --app-id hare-app --run-groups "$RUN_GROUPS" --rules "$RULES"[/
|
|
134
|
+
nextmv cloud ensemble create --app-id hare-app --run-groups "$RUN_GROUPS" --rules "$RULES"[/green]
|
|
134
135
|
|
|
135
136
|
- Create with custom ID, name, and description.
|
|
136
|
-
$ [
|
|
137
|
+
$ [green]RUN_GROUP='{{
|
|
137
138
|
"id": "rg1",
|
|
138
139
|
"instance_id": "inst-123"
|
|
139
140
|
}}'
|
|
@@ -147,10 +148,10 @@ app = typer.Typer()
|
|
|
147
148
|
nextmv cloud ensemble create --app-id hare-app \\
|
|
148
149
|
--ensemble-definition-id prod-ensemble --name "Production Ensemble" \\
|
|
149
150
|
--description "Production ensemble with multiple solvers" \\
|
|
150
|
-
--run-groups "$RUN_GROUP" --rules "$RULE"[/
|
|
151
|
+
--run-groups "$RUN_GROUP" --rules "$RULE"[/green]
|
|
151
152
|
|
|
152
153
|
- Create with run group repetitions.
|
|
153
|
-
$ [
|
|
154
|
+
$ [green]RUN_GROUP='{{
|
|
154
155
|
"id": "rg1",
|
|
155
156
|
"instance_id": "inst-123",
|
|
156
157
|
"repetitions": 5
|
|
@@ -162,7 +163,7 @@ app = typer.Typer()
|
|
|
162
163
|
"tolerance": {{"value": 0.1, "type": "relative"}},
|
|
163
164
|
"index": 0
|
|
164
165
|
}}'
|
|
165
|
-
nextmv cloud ensemble create --app-id hare-app --run-groups "$RUN_GROUP" --rules "$RULE"[/
|
|
166
|
+
nextmv cloud ensemble create --app-id hare-app --run-groups "$RUN_GROUP" --rules "$RULE"[/green]
|
|
166
167
|
"""
|
|
167
168
|
)
|
|
168
169
|
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
|
|
8
9
|
|
|
9
10
|
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,27 +32,31 @@ 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 --yes
|
|
35
|
+
This action is permanent and cannot be undone. Use the [code]--yes[/code]
|
|
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
|
+
$ [green]nextmv cloud ensemble delete --app-id hare-app --ensemble-definition-id prod-ensemble[/green]
|
|
43
43
|
|
|
44
44
|
- Delete the ensemble definition without confirmation prompt.
|
|
45
|
-
$ [
|
|
45
|
+
$ [green]nextmv cloud ensemble delete --app-id hare-app --ensemble-definition-id prod-ensemble --yes[/green]
|
|
46
46
|
"""
|
|
47
47
|
|
|
48
48
|
if not yes:
|
|
49
|
-
confirm =
|
|
49
|
+
confirm = Confirm.ask(
|
|
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,
|
|
52
53
|
)
|
|
53
54
|
|
|
54
55
|
if not confirm:
|
|
55
|
-
info(
|
|
56
|
+
info(
|
|
57
|
+
msg=f"Ensemble definition [magenta]{ensemble_definition_id}[/magenta] will not be deleted.",
|
|
58
|
+
emoji=":bulb:",
|
|
59
|
+
)
|
|
56
60
|
return
|
|
57
61
|
|
|
58
62
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
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
|
+
$ [green]nextmv cloud ensemble get --app-id hare-app \\
|
|
44
|
+
--ensemble-definition-id prod-ensemble[/green]
|
|
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
|
+
$ [green]nextmv cloud ensemble get --app-id hare-app \\
|
|
49
|
+
--ensemble-definition-id prod-ensemble --output ensemble.json[/green]
|
|
50
50
|
"""
|
|
51
51
|
|
|
52
52
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
@@ -58,27 +58,27 @@ def update(
|
|
|
58
58
|
[bold][underline]Examples[/underline][/bold]
|
|
59
59
|
|
|
60
60
|
- Update the name of an ensemble definition.
|
|
61
|
-
$ [
|
|
62
|
-
--ensemble-definition-id prod-ensemble --name "Updated Production Ensemble"[/
|
|
61
|
+
$ [green]nextmv cloud ensemble update --app-id hare-app \\
|
|
62
|
+
--ensemble-definition-id prod-ensemble --name "Updated Production Ensemble"[/green]
|
|
63
63
|
|
|
64
64
|
- Update the description of an ensemble definition.
|
|
65
|
-
$ [
|
|
65
|
+
$ [green]nextmv cloud ensemble update --app-id hare-app \\
|
|
66
66
|
--ensemble-definition-id prod-ensemble \\
|
|
67
|
-
--description "Updated ensemble for production workloads"[/
|
|
67
|
+
--description "Updated ensemble for production workloads"[/green]
|
|
68
68
|
|
|
69
69
|
- Update both name and description.
|
|
70
|
-
$ [
|
|
70
|
+
$ [green]nextmv cloud ensemble update --app-id hare-app \\
|
|
71
71
|
--ensemble-definition-id prod-ensemble --name "Production Ensemble v2" \\
|
|
72
|
-
--description "Enhanced ensemble configuration for production"[/
|
|
72
|
+
--description "Enhanced ensemble configuration for production"[/green]
|
|
73
73
|
|
|
74
74
|
- Update and save the result to a file.
|
|
75
|
-
$ [
|
|
75
|
+
$ [green]nextmv cloud ensemble update --app-id hare-app \\
|
|
76
76
|
--ensemble-definition-id prod-ensemble --name "New Name" \\
|
|
77
|
-
--description "New Description" --output updated.json[/
|
|
77
|
+
--description "New Description" --output updated.json[/green]
|
|
78
78
|
"""
|
|
79
79
|
|
|
80
80
|
if name is None and description is None:
|
|
81
|
-
error("Provide at least one option to update: --name or --description.")
|
|
81
|
+
error("Provide at least one option to update: [code]--name[/code] or [code]--description[/code].")
|
|
82
82
|
|
|
83
83
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
84
84
|
|
|
@@ -5,7 +5,6 @@ This module defines the cloud input-set command tree for the Nextmv CLI.
|
|
|
5
5
|
import typer
|
|
6
6
|
|
|
7
7
|
from nextmv.cli.cloud.input_set.create import app as create_app
|
|
8
|
-
from nextmv.cli.cloud.input_set.delete import app as delete_app
|
|
9
8
|
from nextmv.cli.cloud.input_set.get import app as get_app
|
|
10
9
|
from nextmv.cli.cloud.input_set.list import app as list_app
|
|
11
10
|
from nextmv.cli.cloud.input_set.update import app as update_app
|
|
@@ -13,7 +12,6 @@ from nextmv.cli.cloud.input_set.update import app as update_app
|
|
|
13
12
|
# Set up subcommand application.
|
|
14
13
|
app = typer.Typer()
|
|
15
14
|
app.add_typer(create_app)
|
|
16
|
-
app.add_typer(delete_app)
|
|
17
15
|
app.add_typer(get_app)
|
|
18
16
|
app.add_typer(list_app)
|
|
19
17
|
app.add_typer(update_app)
|
|
@@ -72,8 +72,7 @@ def create(
|
|
|
72
72
|
typer.Option(
|
|
73
73
|
"--start-time",
|
|
74
74
|
formats=["%Y-%m-%dT%H:%M:%S%z"],
|
|
75
|
-
help="Start time for filtering runs
|
|
76
|
-
"Object format: [dim]'2024-01-01T00:00:00Z'[/dim]",
|
|
75
|
+
help="Start time for filtering runs. (example: [magenta]'2024-01-01T00:00:00Z'[/magenta])",
|
|
77
76
|
metavar="START_TIME",
|
|
78
77
|
),
|
|
79
78
|
] = None,
|
|
@@ -82,8 +81,7 @@ def create(
|
|
|
82
81
|
typer.Option(
|
|
83
82
|
"--end-time",
|
|
84
83
|
formats=["%Y-%m-%dT%H:%M:%S%z"],
|
|
85
|
-
help="End time for filtering runs
|
|
86
|
-
"Object format: [dim]'2024-01-01T00:00:00Z'[/dim]",
|
|
84
|
+
help="End time for filtering runs. (example: [magenta]'2024-01-01T00:00:00Z'[/magenta])",
|
|
87
85
|
metavar="END_TIME",
|
|
88
86
|
),
|
|
89
87
|
] = None,
|
|
@@ -96,13 +94,13 @@ def create(
|
|
|
96
94
|
metavar="MAXIMUM_RUNS",
|
|
97
95
|
),
|
|
98
96
|
] = 20,
|
|
99
|
-
|
|
97
|
+
inputs: Annotated[
|
|
100
98
|
str | None,
|
|
101
99
|
typer.Option(
|
|
102
|
-
"--
|
|
103
|
-
help="
|
|
104
|
-
"format: [
|
|
105
|
-
metavar="
|
|
100
|
+
"--inputs",
|
|
101
|
+
help="Inputs for the input set. Data should be valid [magenta]json[/magenta]. Object "
|
|
102
|
+
"format: [magenta][{'id': 'id', 'name': 'name', 'description': 'description'}][/magenta].",
|
|
103
|
+
metavar="INPUTS",
|
|
106
104
|
),
|
|
107
105
|
] = None,
|
|
108
106
|
profile: ProfileOption = None,
|
|
@@ -113,30 +111,32 @@ def create(
|
|
|
113
111
|
An input set is a collection of inputs that can be reused across multiple
|
|
114
112
|
experiments.
|
|
115
113
|
|
|
116
|
-
1. --run-ids: Create from a list of existing run IDs.
|
|
117
|
-
|
|
118
|
-
|
|
114
|
+
1. [code]--run-ids[/code]: Create from a list of existing run IDs.
|
|
115
|
+
|
|
116
|
+
2. [code]--inputs[/code]: Create from existing managed inputs in the application.
|
|
117
|
+
|
|
118
|
+
3. [code]--instance-id[/code] with [code]--start-time[/code] and [code]--end-time[/code]:
|
|
119
119
|
Create from instance runs matching the time range criteria.
|
|
120
120
|
|
|
121
121
|
[bold][underline]Examples[/underline][/bold]
|
|
122
122
|
|
|
123
123
|
- Create an input set for application [magenta]hare-app[/magenta] from runs.
|
|
124
124
|
A random input set ID will be generated if one is not provided.
|
|
125
|
-
$ [
|
|
126
|
-
--name "Hare Input Set" --run-ids run-1 --run-ids run-2 --run-ids run-3"[/
|
|
125
|
+
$ [green]nextmv cloud input-set create --app-id hare-app \\
|
|
126
|
+
--name "Hare Input Set" --run-ids run-1 --run-ids run-2 --run-ids run-3"[/green]
|
|
127
127
|
|
|
128
128
|
- Create an input set with a specific ID.
|
|
129
|
-
$ [
|
|
130
|
-
--name "Hare Input Set" --run-ids run-1 --run-ids run-2 --run-ids run-3"[/
|
|
129
|
+
$ [green]nextmv cloud input-set create --app-id hare-app --input-set-id hare-input-set \\
|
|
130
|
+
--name "Hare Input Set" --run-ids run-1 --run-ids run-2 --run-ids run-3"[/green]
|
|
131
131
|
|
|
132
132
|
- Create an input set using existing managed inputs.
|
|
133
|
-
$ [
|
|
134
|
-
--
|
|
133
|
+
$ [green]nextmv cloud input-set create --app-id hare-app --name "Hare Input Set" \\
|
|
134
|
+
--inputs '[{"id": "hare-input-1", "name": "hare input", "description": "hare description"}]'[/green]
|
|
135
135
|
|
|
136
136
|
- Create an input set from runs using a specific instance and time range.
|
|
137
|
-
$ [
|
|
137
|
+
$ [green]nextmv cloud input-set create --app-id hare-app --name "Hare Input Set" \\
|
|
138
138
|
--instance-id hare-instance --start-time "2024-01-01T00:00:00Z" \\
|
|
139
|
-
--end-time "2024-01-31T23:59:59Z"[/
|
|
139
|
+
--end-time "2024-01-31T23:59:59Z"[/green]
|
|
140
140
|
"""
|
|
141
141
|
|
|
142
142
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
@@ -147,8 +147,8 @@ def create(
|
|
|
147
147
|
input_set_id = safe_id("input-set")
|
|
148
148
|
|
|
149
149
|
managed_inputs = []
|
|
150
|
-
if
|
|
151
|
-
for d in json.loads(
|
|
150
|
+
if inputs is not None:
|
|
151
|
+
for d in json.loads(inputs):
|
|
152
152
|
i = ManagedInput.from_dict(d)
|
|
153
153
|
if i is None:
|
|
154
154
|
error(f"[magenta]{d}[/magenta] is not a valid [yellow]ManagedInput[/yellow]")
|
|
@@ -39,12 +39,12 @@ def get(
|
|
|
39
39
|
[bold][underline]Examples[/underline][/bold]
|
|
40
40
|
|
|
41
41
|
- Get an input set with the ID [magenta]hare-input-set[/magenta].
|
|
42
|
-
$ [
|
|
42
|
+
$ [green]nextmv cloud input-set get --app-id hare-app --input-set-id hare-input-set[/green]
|
|
43
43
|
|
|
44
44
|
- Get an input set with the ID [magenta]hare-input-set[/magenta] and save
|
|
45
45
|
the information to a [magenta]input-set.json[/magenta] file.
|
|
46
|
-
$ [
|
|
47
|
-
--output input-set.json[/
|
|
46
|
+
$ [green]nextmv cloud input-set get --app-id hare-app --input-set-id hare-input-set \\
|
|
47
|
+
--output input-set.json[/green]
|
|
48
48
|
"""
|
|
49
49
|
|
|
50
50
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
@@ -38,13 +38,13 @@ def list(
|
|
|
38
38
|
[bold][underline]Examples[/underline][/bold]
|
|
39
39
|
|
|
40
40
|
- List all input sets of application [magenta]hare-app[/magenta].
|
|
41
|
-
$ [
|
|
41
|
+
$ [green]nextmv cloud input-set list --app-id hare-app[/green]
|
|
42
42
|
|
|
43
43
|
- List all input sets using the profile named [magenta]hare[/magenta].
|
|
44
|
-
$ [
|
|
44
|
+
$ [green]nextmv cloud input-set list --app-id hare-app --profile hare[/green]
|
|
45
45
|
|
|
46
46
|
- List all input sets and save the information to a [magenta]input-sets.json[/magenta] file.
|
|
47
|
-
$ [
|
|
47
|
+
$ [green]nextmv cloud input-set list --app-id hare-app --output input-sets.json[/green]
|
|
48
48
|
"""
|
|
49
49
|
|
|
50
50
|
cloud_app = build_app(app_id=app_id, profile=profile)
|