nextmv 0.39.0.dev1__py3-none-any.whl → 1.0.0__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 +1 -2
- nextmv/__init__.py +2 -4
- nextmv/cli/CONTRIBUTING.md +583 -0
- nextmv/cli/cloud/__init__.py +49 -0
- nextmv/cli/cloud/acceptance/__init__.py +27 -0
- nextmv/cli/cloud/acceptance/create.py +391 -0
- nextmv/cli/cloud/acceptance/delete.py +64 -0
- nextmv/cli/cloud/acceptance/get.py +103 -0
- nextmv/cli/cloud/acceptance/list.py +62 -0
- nextmv/cli/cloud/acceptance/update.py +95 -0
- nextmv/cli/cloud/account/__init__.py +28 -0
- nextmv/cli/cloud/account/create.py +83 -0
- nextmv/cli/cloud/account/delete.py +59 -0
- nextmv/cli/cloud/account/get.py +66 -0
- nextmv/cli/cloud/account/update.py +70 -0
- nextmv/cli/cloud/app/__init__.py +35 -0
- nextmv/cli/cloud/app/create.py +140 -0
- nextmv/cli/cloud/app/delete.py +57 -0
- nextmv/cli/cloud/app/exists.py +44 -0
- nextmv/cli/cloud/app/get.py +66 -0
- nextmv/cli/cloud/app/list.py +61 -0
- nextmv/cli/cloud/app/push.py +432 -0
- nextmv/cli/cloud/app/update.py +124 -0
- nextmv/cli/cloud/batch/__init__.py +29 -0
- nextmv/cli/cloud/batch/create.py +452 -0
- nextmv/cli/cloud/batch/delete.py +64 -0
- nextmv/cli/cloud/batch/get.py +104 -0
- nextmv/cli/cloud/batch/list.py +63 -0
- nextmv/cli/cloud/batch/metadata.py +66 -0
- nextmv/cli/cloud/batch/update.py +95 -0
- nextmv/cli/cloud/data/__init__.py +26 -0
- nextmv/cli/cloud/data/upload.py +162 -0
- nextmv/cli/cloud/ensemble/__init__.py +33 -0
- nextmv/cli/cloud/ensemble/create.py +413 -0
- nextmv/cli/cloud/ensemble/delete.py +63 -0
- nextmv/cli/cloud/ensemble/get.py +65 -0
- nextmv/cli/cloud/ensemble/list.py +63 -0
- nextmv/cli/cloud/ensemble/update.py +103 -0
- nextmv/cli/cloud/input_set/__init__.py +32 -0
- nextmv/cli/cloud/input_set/create.py +168 -0
- nextmv/cli/cloud/input_set/delete.py +64 -0
- nextmv/cli/cloud/input_set/get.py +63 -0
- nextmv/cli/cloud/input_set/list.py +63 -0
- nextmv/cli/cloud/input_set/update.py +123 -0
- nextmv/cli/cloud/instance/__init__.py +35 -0
- nextmv/cli/cloud/instance/create.py +289 -0
- nextmv/cli/cloud/instance/delete.py +61 -0
- nextmv/cli/cloud/instance/exists.py +39 -0
- nextmv/cli/cloud/instance/get.py +62 -0
- nextmv/cli/cloud/instance/list.py +60 -0
- nextmv/cli/cloud/instance/update.py +216 -0
- nextmv/cli/cloud/managed_input/__init__.py +31 -0
- nextmv/cli/cloud/managed_input/create.py +144 -0
- nextmv/cli/cloud/managed_input/delete.py +64 -0
- nextmv/cli/cloud/managed_input/get.py +63 -0
- nextmv/cli/cloud/managed_input/list.py +60 -0
- nextmv/cli/cloud/managed_input/update.py +97 -0
- nextmv/cli/cloud/run/__init__.py +37 -0
- nextmv/cli/cloud/run/cancel.py +37 -0
- nextmv/cli/cloud/run/create.py +524 -0
- nextmv/cli/cloud/run/get.py +199 -0
- nextmv/cli/cloud/run/input.py +86 -0
- nextmv/cli/cloud/run/list.py +80 -0
- nextmv/cli/cloud/run/logs.py +166 -0
- nextmv/cli/cloud/run/metadata.py +67 -0
- nextmv/cli/cloud/run/track.py +500 -0
- nextmv/cli/cloud/scenario/__init__.py +29 -0
- nextmv/cli/cloud/scenario/create.py +451 -0
- nextmv/cli/cloud/scenario/delete.py +61 -0
- nextmv/cli/cloud/scenario/get.py +102 -0
- nextmv/cli/cloud/scenario/list.py +63 -0
- nextmv/cli/cloud/scenario/metadata.py +67 -0
- nextmv/cli/cloud/scenario/update.py +93 -0
- nextmv/cli/cloud/secrets/__init__.py +33 -0
- nextmv/cli/cloud/secrets/create.py +206 -0
- nextmv/cli/cloud/secrets/delete.py +63 -0
- nextmv/cli/cloud/secrets/get.py +66 -0
- nextmv/cli/cloud/secrets/list.py +60 -0
- nextmv/cli/cloud/secrets/update.py +144 -0
- nextmv/cli/cloud/shadow/__init__.py +33 -0
- nextmv/cli/cloud/shadow/create.py +184 -0
- nextmv/cli/cloud/shadow/delete.py +64 -0
- nextmv/cli/cloud/shadow/get.py +61 -0
- nextmv/cli/cloud/shadow/list.py +63 -0
- nextmv/cli/cloud/shadow/metadata.py +66 -0
- nextmv/cli/cloud/shadow/start.py +43 -0
- nextmv/cli/cloud/shadow/stop.py +53 -0
- nextmv/cli/cloud/shadow/update.py +96 -0
- nextmv/cli/cloud/switchback/__init__.py +33 -0
- nextmv/cli/cloud/switchback/create.py +151 -0
- nextmv/cli/cloud/switchback/delete.py +64 -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 +53 -0
- nextmv/cli/cloud/switchback/update.py +96 -0
- nextmv/cli/cloud/upload/__init__.py +22 -0
- nextmv/cli/cloud/upload/create.py +39 -0
- nextmv/cli/cloud/version/__init__.py +33 -0
- nextmv/cli/cloud/version/create.py +96 -0
- nextmv/cli/cloud/version/delete.py +61 -0
- nextmv/cli/cloud/version/exists.py +39 -0
- nextmv/cli/cloud/version/get.py +62 -0
- nextmv/cli/cloud/version/list.py +60 -0
- nextmv/cli/cloud/version/update.py +92 -0
- nextmv/cli/community/__init__.py +24 -0
- nextmv/cli/community/clone.py +86 -0
- nextmv/cli/community/list.py +200 -0
- nextmv/cli/configuration/__init__.py +23 -0
- nextmv/cli/configuration/config.py +228 -0
- nextmv/cli/configuration/create.py +94 -0
- nextmv/cli/configuration/delete.py +67 -0
- nextmv/cli/configuration/list.py +77 -0
- nextmv/cli/confirm.py +34 -0
- nextmv/cli/main.py +161 -3
- nextmv/cli/message.py +170 -0
- nextmv/cli/options.py +220 -0
- nextmv/cli/version.py +22 -2
- nextmv/cloud/__init__.py +17 -38
- nextmv/cloud/acceptance_test.py +20 -83
- nextmv/cloud/account.py +269 -30
- nextmv/cloud/application/__init__.py +898 -0
- nextmv/cloud/application/_acceptance.py +424 -0
- nextmv/cloud/application/_batch_scenario.py +845 -0
- nextmv/cloud/application/_ensemble.py +251 -0
- nextmv/cloud/application/_input_set.py +263 -0
- nextmv/cloud/application/_instance.py +289 -0
- nextmv/cloud/application/_managed_input.py +227 -0
- nextmv/cloud/application/_run.py +1393 -0
- nextmv/cloud/application/_secrets.py +294 -0
- nextmv/cloud/application/_shadow.py +320 -0
- nextmv/cloud/application/_switchback.py +332 -0
- nextmv/cloud/application/_utils.py +54 -0
- nextmv/cloud/application/_version.py +304 -0
- nextmv/cloud/batch_experiment.py +6 -2
- nextmv/cloud/community.py +446 -0
- nextmv/cloud/instance.py +11 -1
- nextmv/cloud/integration.py +8 -5
- nextmv/cloud/package.py +50 -9
- nextmv/cloud/shadow.py +254 -0
- nextmv/cloud/switchback.py +228 -0
- nextmv/deprecated.py +5 -3
- nextmv/input.py +20 -88
- nextmv/local/application.py +3 -15
- nextmv/local/runner.py +1 -1
- nextmv/model.py +50 -11
- nextmv/options.py +11 -256
- nextmv/output.py +0 -62
- nextmv/polling.py +54 -16
- nextmv/run.py +84 -37
- nextmv/status.py +1 -51
- {nextmv-0.39.0.dev1.dist-info → nextmv-1.0.0.dist-info}/METADATA +37 -11
- nextmv-1.0.0.dist-info/RECORD +185 -0
- nextmv-1.0.0.dist-info/entry_points.txt +2 -0
- nextmv/cloud/application.py +0 -4204
- nextmv-0.39.0.dev1.dist-info/RECORD +0 -55
- nextmv-0.39.0.dev1.dist-info/entry_points.txt +0 -2
- {nextmv-0.39.0.dev1.dist-info → nextmv-1.0.0.dist-info}/WHEEL +0 -0
- {nextmv-0.39.0.dev1.dist-info → nextmv-1.0.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module defines the cloud ensemble update 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 error, print_json, success
|
|
12
|
+
from nextmv.cli.options import AppIDOption, EnsembleDefinitionIDOption, ProfileOption
|
|
13
|
+
|
|
14
|
+
# Set up subcommand application.
|
|
15
|
+
app = typer.Typer()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@app.command()
|
|
19
|
+
def update(
|
|
20
|
+
app_id: AppIDOption,
|
|
21
|
+
ensemble_definition_id: EnsembleDefinitionIDOption,
|
|
22
|
+
description: Annotated[
|
|
23
|
+
str | None,
|
|
24
|
+
typer.Option(
|
|
25
|
+
"--description",
|
|
26
|
+
"-d",
|
|
27
|
+
help="A new description for the ensemble definition.",
|
|
28
|
+
metavar="DESCRIPTION",
|
|
29
|
+
),
|
|
30
|
+
] = None,
|
|
31
|
+
name: Annotated[
|
|
32
|
+
str | None,
|
|
33
|
+
typer.Option(
|
|
34
|
+
"--name",
|
|
35
|
+
"-n",
|
|
36
|
+
help="A new name for the ensemble definition.",
|
|
37
|
+
metavar="NAME",
|
|
38
|
+
),
|
|
39
|
+
] = None,
|
|
40
|
+
output: Annotated[
|
|
41
|
+
str | None,
|
|
42
|
+
typer.Option(
|
|
43
|
+
"--output",
|
|
44
|
+
"-o",
|
|
45
|
+
help="Saves the updated ensemble definition information to this location.",
|
|
46
|
+
metavar="OUTPUT_PATH",
|
|
47
|
+
),
|
|
48
|
+
] = None,
|
|
49
|
+
profile: ProfileOption = None,
|
|
50
|
+
) -> None:
|
|
51
|
+
"""
|
|
52
|
+
Update a Nextmv Cloud ensemble definition.
|
|
53
|
+
|
|
54
|
+
You can update the name and/or description of an existing ensemble
|
|
55
|
+
definition. To modify run groups or evaluation rules, you need to delete
|
|
56
|
+
and recreate the ensemble definition.
|
|
57
|
+
|
|
58
|
+
[bold][underline]Examples[/underline][/bold]
|
|
59
|
+
|
|
60
|
+
- Update the name of an ensemble definition.
|
|
61
|
+
$ [dim]nextmv cloud ensemble update --app-id hare-app \\
|
|
62
|
+
--ensemble-definition-id prod-ensemble --name "Updated Production Ensemble"[/dim]
|
|
63
|
+
|
|
64
|
+
- Update the description of an ensemble definition.
|
|
65
|
+
$ [dim]nextmv cloud ensemble update --app-id hare-app \\
|
|
66
|
+
--ensemble-definition-id prod-ensemble \\
|
|
67
|
+
--description "Updated ensemble for production workloads"[/dim]
|
|
68
|
+
|
|
69
|
+
- Update both name and description.
|
|
70
|
+
$ [dim]nextmv cloud ensemble update --app-id hare-app \\
|
|
71
|
+
--ensemble-definition-id prod-ensemble --name "Production Ensemble v2" \\
|
|
72
|
+
--description "Enhanced ensemble configuration for production"[/dim]
|
|
73
|
+
|
|
74
|
+
- Update and save the result to a file.
|
|
75
|
+
$ [dim]nextmv cloud ensemble update --app-id hare-app \\
|
|
76
|
+
--ensemble-definition-id prod-ensemble --name "New Name" \\
|
|
77
|
+
--description "New Description" --output updated.json[/dim]
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
if name is None and description is None:
|
|
81
|
+
error("Provide at least one option to update: --name or --description.")
|
|
82
|
+
|
|
83
|
+
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
84
|
+
|
|
85
|
+
ensemble_definition = cloud_app.update_ensemble_definition(
|
|
86
|
+
id=ensemble_definition_id,
|
|
87
|
+
name=name,
|
|
88
|
+
description=description,
|
|
89
|
+
)
|
|
90
|
+
success(
|
|
91
|
+
f"Ensemble definition [magenta]{ensemble_definition_id}[/magenta] updated successfully "
|
|
92
|
+
f"in application [magenta]{app_id}[/magenta]."
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
if output is not None and output != "":
|
|
96
|
+
with open(output, "w") as f:
|
|
97
|
+
json.dump(ensemble_definition.to_dict(), f, indent=2)
|
|
98
|
+
|
|
99
|
+
success(msg=f"Updated ensemble definition information saved to [magenta]{output}[/magenta].")
|
|
100
|
+
|
|
101
|
+
return
|
|
102
|
+
|
|
103
|
+
print_json(ensemble_definition.to_dict())
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module defines the cloud input-set command tree for the Nextmv CLI.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
|
|
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
|
+
from nextmv.cli.cloud.input_set.get import app as get_app
|
|
10
|
+
from nextmv.cli.cloud.input_set.list import app as list_app
|
|
11
|
+
from nextmv.cli.cloud.input_set.update import app as update_app
|
|
12
|
+
|
|
13
|
+
# Set up subcommand application.
|
|
14
|
+
app = typer.Typer()
|
|
15
|
+
app.add_typer(create_app)
|
|
16
|
+
app.add_typer(delete_app)
|
|
17
|
+
app.add_typer(get_app)
|
|
18
|
+
app.add_typer(list_app)
|
|
19
|
+
app.add_typer(update_app)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@app.callback()
|
|
23
|
+
def callback() -> None:
|
|
24
|
+
"""
|
|
25
|
+
Create and manage Nextmv Cloud input sets.
|
|
26
|
+
|
|
27
|
+
An input set is a collection of inputs from associated runs that can be
|
|
28
|
+
reused across multiple experiments. Input sets allow you to test different
|
|
29
|
+
configurations of your decision model using the same set of inputs for
|
|
30
|
+
consistent comparison.
|
|
31
|
+
"""
|
|
32
|
+
pass
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module defines the cloud input-set create command for the Nextmv CLI.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
from typing import Annotated
|
|
8
|
+
|
|
9
|
+
import typer
|
|
10
|
+
|
|
11
|
+
from nextmv.cli.configuration.config import build_app
|
|
12
|
+
from nextmv.cli.message import error, in_progress, print_json
|
|
13
|
+
from nextmv.cli.options import AppIDOption, ProfileOption
|
|
14
|
+
from nextmv.cloud.input_set import ManagedInput
|
|
15
|
+
from nextmv.safe import safe_id
|
|
16
|
+
|
|
17
|
+
# Set up subcommand application.
|
|
18
|
+
app = typer.Typer()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@app.command()
|
|
22
|
+
def create(
|
|
23
|
+
app_id: AppIDOption,
|
|
24
|
+
name: Annotated[
|
|
25
|
+
str,
|
|
26
|
+
typer.Option(
|
|
27
|
+
"--name",
|
|
28
|
+
"-n",
|
|
29
|
+
help="A name for the input set.",
|
|
30
|
+
metavar="NAME",
|
|
31
|
+
),
|
|
32
|
+
],
|
|
33
|
+
input_set_id: Annotated[
|
|
34
|
+
str | None,
|
|
35
|
+
typer.Option(
|
|
36
|
+
"--input-set-id",
|
|
37
|
+
"-s",
|
|
38
|
+
help="An optional ID for the input set. If not provided, a random ID will be generated.",
|
|
39
|
+
envvar="NEXTMV_INPUT_SET_ID",
|
|
40
|
+
metavar="INPUT_SET_ID",
|
|
41
|
+
),
|
|
42
|
+
] = None,
|
|
43
|
+
instance_id: Annotated[
|
|
44
|
+
str | None,
|
|
45
|
+
typer.Option(
|
|
46
|
+
"--instance-id",
|
|
47
|
+
"-i",
|
|
48
|
+
help="Instance ID to filter runs from.",
|
|
49
|
+
metavar="INSTANCE_ID",
|
|
50
|
+
),
|
|
51
|
+
] = None,
|
|
52
|
+
description: Annotated[
|
|
53
|
+
str | None,
|
|
54
|
+
typer.Option(
|
|
55
|
+
"--description",
|
|
56
|
+
"-d",
|
|
57
|
+
help="An optional description for the input set.",
|
|
58
|
+
metavar="DESCRIPTION",
|
|
59
|
+
),
|
|
60
|
+
] = None,
|
|
61
|
+
run_ids: Annotated[
|
|
62
|
+
list[str] | None,
|
|
63
|
+
typer.Option(
|
|
64
|
+
"--run-ids",
|
|
65
|
+
"-r",
|
|
66
|
+
help="List of run IDs to include in the input set (max 20). Pass multiple run IDs by repeating the flag.",
|
|
67
|
+
metavar="RUN_IDS",
|
|
68
|
+
),
|
|
69
|
+
] = None,
|
|
70
|
+
start_time: Annotated[
|
|
71
|
+
datetime | None,
|
|
72
|
+
typer.Option(
|
|
73
|
+
"--start-time",
|
|
74
|
+
formats=["%Y-%m-%dT%H:%M:%S%z"],
|
|
75
|
+
help="Start time for filtering runs in [magenta]RFC 3339[/magenta] format. "
|
|
76
|
+
"Object format: [dim]'2024-01-01T00:00:00Z'[/dim]",
|
|
77
|
+
metavar="START_TIME",
|
|
78
|
+
),
|
|
79
|
+
] = None,
|
|
80
|
+
end_time: Annotated[
|
|
81
|
+
datetime | None,
|
|
82
|
+
typer.Option(
|
|
83
|
+
"--end-time",
|
|
84
|
+
formats=["%Y-%m-%dT%H:%M:%S%z"],
|
|
85
|
+
help="End time for filtering runs in [magenta]RFC 3339[/magenta] format. "
|
|
86
|
+
"Object format: [dim]'2024-01-01T00:00:00Z'[/dim]",
|
|
87
|
+
metavar="END_TIME",
|
|
88
|
+
),
|
|
89
|
+
] = None,
|
|
90
|
+
maximum_runs: Annotated[
|
|
91
|
+
int | None,
|
|
92
|
+
typer.Option(
|
|
93
|
+
"--maximum-runs",
|
|
94
|
+
"-m",
|
|
95
|
+
help="Maximum number of runs to include (max [magenta]20[/magenta]).",
|
|
96
|
+
metavar="MAXIMUM_RUNS",
|
|
97
|
+
),
|
|
98
|
+
] = 20,
|
|
99
|
+
managed_inputs: Annotated[
|
|
100
|
+
str | None,
|
|
101
|
+
typer.Option(
|
|
102
|
+
"--managed-inputs",
|
|
103
|
+
help="Managed inputs for the input set. Data should be valid [magenta]json[/magenta]. Object "
|
|
104
|
+
"format: [dim][{'id': 'id', 'name': 'name', 'description': 'description'}][/dim].",
|
|
105
|
+
metavar="MANAGED_INPUTS",
|
|
106
|
+
),
|
|
107
|
+
] = None,
|
|
108
|
+
profile: ProfileOption = None,
|
|
109
|
+
) -> None:
|
|
110
|
+
"""
|
|
111
|
+
Create a new Nextmv Cloud input set for experiments.
|
|
112
|
+
|
|
113
|
+
An input set is a collection of inputs that can be reused across multiple
|
|
114
|
+
experiments.
|
|
115
|
+
|
|
116
|
+
1. --run-ids: Create from a list of existing run IDs.
|
|
117
|
+
2. --managed-inputs: Create from existing managed inputs in the application.
|
|
118
|
+
3. --instance-id with --start-time and --end-time:
|
|
119
|
+
Create from instance runs matching the time range criteria.
|
|
120
|
+
|
|
121
|
+
[bold][underline]Examples[/underline][/bold]
|
|
122
|
+
|
|
123
|
+
- Create an input set for application [magenta]hare-app[/magenta] from runs.
|
|
124
|
+
A random input set ID will be generated if one is not provided.
|
|
125
|
+
$ [dim]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"[/dim]
|
|
127
|
+
|
|
128
|
+
- Create an input set with a specific ID.
|
|
129
|
+
$ [dim]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"[/dim]
|
|
131
|
+
|
|
132
|
+
- Create an input set using existing managed inputs.
|
|
133
|
+
$ [dim]nextmv cloud input-set create --app-id hare-app --name "Hare Input Set" \\
|
|
134
|
+
--managed-inputs '[{"id": "hare-input-1", "name": "hare input", "description": "hare description"}]'[/dim]
|
|
135
|
+
|
|
136
|
+
- Create an input set from runs using a specific instance and time range.
|
|
137
|
+
$ [dim]nextmv cloud input-set create --app-id hare-app --name "Hare Input Set" \\
|
|
138
|
+
--instance-id hare-instance --start-time "2024-01-01T00:00:00Z" \\
|
|
139
|
+
--end-time "2024-01-31T23:59:59Z"[/dim]
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
143
|
+
in_progress(msg="Creating input set...")
|
|
144
|
+
|
|
145
|
+
# Generate a random input set ID if one is not provided.
|
|
146
|
+
if input_set_id is None:
|
|
147
|
+
input_set_id = safe_id("input-set")
|
|
148
|
+
|
|
149
|
+
managed_inputs = []
|
|
150
|
+
if managed_inputs is not None:
|
|
151
|
+
for d in json.loads(managed_inputs):
|
|
152
|
+
i = ManagedInput.from_dict(d)
|
|
153
|
+
if i is None:
|
|
154
|
+
error(f"[magenta]{d}[/magenta] is not a valid [yellow]ManagedInput[/yellow]")
|
|
155
|
+
managed_inputs.append(i)
|
|
156
|
+
|
|
157
|
+
input_set = cloud_app.new_input_set(
|
|
158
|
+
input_set_id,
|
|
159
|
+
name,
|
|
160
|
+
description=description,
|
|
161
|
+
instance_id=instance_id,
|
|
162
|
+
run_ids=run_ids,
|
|
163
|
+
start_time=start_time,
|
|
164
|
+
end_time=end_time,
|
|
165
|
+
maximum_runs=maximum_runs,
|
|
166
|
+
inputs=managed_inputs,
|
|
167
|
+
)
|
|
168
|
+
print_json(input_set.to_dict())
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module defines the cloud input-set delete command for the Nextmv CLI.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Annotated
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
|
|
9
|
+
from nextmv.cli.configuration.config import build_app
|
|
10
|
+
from nextmv.cli.confirm import get_confirmation
|
|
11
|
+
from nextmv.cli.message import info, success
|
|
12
|
+
from nextmv.cli.options import AppIDOption, InputSetIDOption, ProfileOption
|
|
13
|
+
|
|
14
|
+
# Set up subcommand application.
|
|
15
|
+
app = typer.Typer()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@app.command()
|
|
19
|
+
def delete(
|
|
20
|
+
app_id: AppIDOption,
|
|
21
|
+
input_set_id: InputSetIDOption,
|
|
22
|
+
yes: Annotated[
|
|
23
|
+
bool,
|
|
24
|
+
typer.Option(
|
|
25
|
+
"--yes",
|
|
26
|
+
"-y",
|
|
27
|
+
help="Agree to deletion confirmation prompt. Useful for non-interactive sessions.",
|
|
28
|
+
),
|
|
29
|
+
] = False,
|
|
30
|
+
profile: ProfileOption = None,
|
|
31
|
+
) -> None:
|
|
32
|
+
"""
|
|
33
|
+
Deletes a Nextmv Cloud input set.
|
|
34
|
+
|
|
35
|
+
This action is permanent and cannot be undone. The input set and all
|
|
36
|
+
associated data will be deleted. Use the --yes flag to skip the
|
|
37
|
+
confirmation prompt.
|
|
38
|
+
|
|
39
|
+
[bold][underline]Examples[/underline][/bold]
|
|
40
|
+
|
|
41
|
+
- Delete the input set with the ID [magenta]hop-analysis[/magenta] from application
|
|
42
|
+
[magenta]hare-app[/magenta].
|
|
43
|
+
$ [dim]nextmv cloud input-set delete --app-id hare-app --input-set-id hop-analysis[/dim]
|
|
44
|
+
|
|
45
|
+
- Delete the input set without confirmation prompt.
|
|
46
|
+
$ [dim]nextmv cloud input-set delete --app-id hare-app --input-set-id carrot-routes --yes[/dim]
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
if not yes:
|
|
50
|
+
confirm = get_confirmation(
|
|
51
|
+
f"Are you sure you want to delete input set [magenta]{input_set_id}[/magenta] "
|
|
52
|
+
f"from application [magenta]{app_id}[/magenta]? This action cannot be undone.",
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
if not confirm:
|
|
56
|
+
info(f"Input set [magenta]{input_set_id}[/magenta] will not be deleted.")
|
|
57
|
+
return
|
|
58
|
+
|
|
59
|
+
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
60
|
+
cloud_app.delete_input_set(input_set_id=input_set_id)
|
|
61
|
+
success(
|
|
62
|
+
f"Input set [magenta]{input_set_id}[/magenta] deleted successfully "
|
|
63
|
+
f"from application [magenta]{app_id}[/magenta]."
|
|
64
|
+
)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module defines the cloud input-set get 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, InputSetIDOption, ProfileOption
|
|
13
|
+
|
|
14
|
+
# Set up subcommand application.
|
|
15
|
+
app = typer.Typer()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@app.command()
|
|
19
|
+
def get(
|
|
20
|
+
app_id: AppIDOption,
|
|
21
|
+
input_set_id: InputSetIDOption,
|
|
22
|
+
output: Annotated[
|
|
23
|
+
str | None,
|
|
24
|
+
typer.Option(
|
|
25
|
+
"--output",
|
|
26
|
+
"-o",
|
|
27
|
+
help="Saves the input set information to this location.",
|
|
28
|
+
metavar="OUTPUT_PATH",
|
|
29
|
+
),
|
|
30
|
+
] = None,
|
|
31
|
+
profile: ProfileOption = None,
|
|
32
|
+
) -> None:
|
|
33
|
+
"""
|
|
34
|
+
Get an Nextmv Cloud input set.
|
|
35
|
+
|
|
36
|
+
This command retrieves the details of an existing input set, including
|
|
37
|
+
its name, description, and the list of inputs it contains.
|
|
38
|
+
|
|
39
|
+
[bold][underline]Examples[/underline][/bold]
|
|
40
|
+
|
|
41
|
+
- Get an input set with the ID [magenta]hare-input-set[/magenta].
|
|
42
|
+
$ [dim]nextmv cloud input-set get --app-id hare-app --input-set-id hare-input-set[/dim]
|
|
43
|
+
|
|
44
|
+
- Get an input set with the ID [magenta]hare-input-set[/magenta] and save
|
|
45
|
+
the information to a [magenta]input-set.json[/magenta] file.
|
|
46
|
+
$ [dim]nextmv cloud input-set get --app-id hare-app --input-set-id hare-input-set \\
|
|
47
|
+
--output input-set.json[/dim]
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
51
|
+
in_progress(msg="Getting input set...")
|
|
52
|
+
input_set = cloud_app.input_set(input_set_id=input_set_id)
|
|
53
|
+
input_set_dict = input_set.to_dict()
|
|
54
|
+
|
|
55
|
+
if output is not None and output != "":
|
|
56
|
+
with open(output, "w") as f:
|
|
57
|
+
json.dump(input_set_dict, f, indent=2)
|
|
58
|
+
|
|
59
|
+
success(msg=f"Input set information saved to [magenta]{output}[/magenta].")
|
|
60
|
+
|
|
61
|
+
return
|
|
62
|
+
|
|
63
|
+
print_json(input_set_dict)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module defines the cloud input-set 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 input set list to this location.",
|
|
27
|
+
metavar="OUTPUT_PATH",
|
|
28
|
+
),
|
|
29
|
+
] = None,
|
|
30
|
+
profile: ProfileOption = None,
|
|
31
|
+
) -> None:
|
|
32
|
+
"""
|
|
33
|
+
List all input sets of a Nextmv Cloud application.
|
|
34
|
+
|
|
35
|
+
This command retrieves all input sets that exist for a given Nextmv Cloud
|
|
36
|
+
application.
|
|
37
|
+
|
|
38
|
+
[bold][underline]Examples[/underline][/bold]
|
|
39
|
+
|
|
40
|
+
- List all input sets of application [magenta]hare-app[/magenta].
|
|
41
|
+
$ [dim]nextmv cloud input-set list --app-id hare-app[/dim]
|
|
42
|
+
|
|
43
|
+
- List all input sets using the profile named [magenta]hare[/magenta].
|
|
44
|
+
$ [dim]nextmv cloud input-set list --app-id hare-app --profile hare[/dim]
|
|
45
|
+
|
|
46
|
+
- List all input sets and save the information to a [magenta]input-sets.json[/magenta] file.
|
|
47
|
+
$ [dim]nextmv cloud input-set list --app-id hare-app --output input-sets.json[/dim]
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
51
|
+
in_progress(msg="Listing input sets...")
|
|
52
|
+
input_sets = cloud_app.list_input_sets()
|
|
53
|
+
input_sets_dicts = [input_set.to_dict() for input_set in input_sets]
|
|
54
|
+
|
|
55
|
+
if output is not None and output != "":
|
|
56
|
+
with open(output, "w") as f:
|
|
57
|
+
json.dump(input_sets_dicts, f, indent=2)
|
|
58
|
+
|
|
59
|
+
success(msg=f"Input set list information saved to [magenta]{output}[/magenta].")
|
|
60
|
+
|
|
61
|
+
return
|
|
62
|
+
|
|
63
|
+
print_json(input_sets_dicts)
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module defines the cloud input-set update 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 error, in_progress, print_json, success
|
|
12
|
+
from nextmv.cli.options import AppIDOption, InputSetIDOption, ProfileOption
|
|
13
|
+
from nextmv.cloud.input_set import ManagedInput
|
|
14
|
+
|
|
15
|
+
# Set up subcommand application.
|
|
16
|
+
app = typer.Typer()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@app.command()
|
|
20
|
+
def update(
|
|
21
|
+
app_id: AppIDOption,
|
|
22
|
+
input_set_id: InputSetIDOption,
|
|
23
|
+
name: Annotated[
|
|
24
|
+
str | None,
|
|
25
|
+
typer.Option(
|
|
26
|
+
"--name",
|
|
27
|
+
"-n",
|
|
28
|
+
help="A new name for the input set.",
|
|
29
|
+
metavar="NAME",
|
|
30
|
+
),
|
|
31
|
+
] = None,
|
|
32
|
+
description: Annotated[
|
|
33
|
+
str | None,
|
|
34
|
+
typer.Option(
|
|
35
|
+
"--description",
|
|
36
|
+
"-d",
|
|
37
|
+
help="A new description for the input set.",
|
|
38
|
+
metavar="DESCRIPTION",
|
|
39
|
+
),
|
|
40
|
+
] = None,
|
|
41
|
+
managed_inputs: Annotated[
|
|
42
|
+
str | None,
|
|
43
|
+
typer.Option(
|
|
44
|
+
"--managed-inputs",
|
|
45
|
+
help="Managed inputs for the input set. Data should be valid [magenta]json[/magenta]. Object "
|
|
46
|
+
"format: [dim][{'id': 'id', 'name': 'name', 'description': 'description'}][/dim].",
|
|
47
|
+
metavar="MANAGED_INPUTS",
|
|
48
|
+
),
|
|
49
|
+
] = None,
|
|
50
|
+
output: Annotated[
|
|
51
|
+
str | None,
|
|
52
|
+
typer.Option(
|
|
53
|
+
"--output",
|
|
54
|
+
"-o",
|
|
55
|
+
help="Saves the updated input set information to this location.",
|
|
56
|
+
metavar="OUTPUT_PATH",
|
|
57
|
+
),
|
|
58
|
+
] = None,
|
|
59
|
+
profile: ProfileOption = None,
|
|
60
|
+
) -> None:
|
|
61
|
+
"""
|
|
62
|
+
Updates a Nextmv Cloud input set.
|
|
63
|
+
|
|
64
|
+
This command updates the metadata of an existing input set. You can update
|
|
65
|
+
the name, description, or managed inputs of the input set.
|
|
66
|
+
|
|
67
|
+
[bold][underline]Examples[/underline][/bold]
|
|
68
|
+
|
|
69
|
+
- Update an input set's name.
|
|
70
|
+
$ [dim]nextmv cloud input-set update --app-id hare-app \\
|
|
71
|
+
--input-set-id hare-input-set --name "New Name"[/dim]
|
|
72
|
+
|
|
73
|
+
- Update an input set's description.
|
|
74
|
+
$ [dim]nextmv cloud input-set update --app-id hare-app \\
|
|
75
|
+
--input-set-id hare-input-set --description "Updated description"[/dim]
|
|
76
|
+
|
|
77
|
+
- Update an input set's managed inputs.
|
|
78
|
+
$ [dim]nextmv cloud input-set update --app-id hare-app --input-set-id hare-input-set \\
|
|
79
|
+
--managed-inputs '[{"id": "hare-input-1", "name": "hare input", "description": "hare description"}]'[/dim]
|
|
80
|
+
|
|
81
|
+
- Update both name and description.
|
|
82
|
+
$ [dim]nextmv cloud input-set update --app-id hare-app --input-set-id hare-input-set \\
|
|
83
|
+
--name "New Name" --description "Updated description"[/dim]
|
|
84
|
+
|
|
85
|
+
- Update and save to a file.
|
|
86
|
+
$ [dim]nextmv cloud input-set update --app-id hare-app --input-set-id hare-input-set \\
|
|
87
|
+
--name "New Name" --output updated_input_set.json[/dim]
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
if name is None and description is None and managed_inputs is None:
|
|
91
|
+
error("Provide at least one option: --name, --description, or --managed-inputs.")
|
|
92
|
+
|
|
93
|
+
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
94
|
+
in_progress(msg="Updating input set...")
|
|
95
|
+
|
|
96
|
+
managed_input_list = []
|
|
97
|
+
if managed_inputs is not None:
|
|
98
|
+
for d in json.loads(managed_inputs):
|
|
99
|
+
i = ManagedInput.from_dict(d)
|
|
100
|
+
if i is None:
|
|
101
|
+
error(f"[magenta]{d}[/magenta] is not a valid [yellow]ManagedInput[/yellow]")
|
|
102
|
+
managed_input_list.append(i)
|
|
103
|
+
|
|
104
|
+
updated_input_set = cloud_app.update_input_set(
|
|
105
|
+
id=input_set_id,
|
|
106
|
+
name=name,
|
|
107
|
+
description=description,
|
|
108
|
+
inputs=managed_input_list,
|
|
109
|
+
)
|
|
110
|
+
success(
|
|
111
|
+
f"Input set [magenta]{input_set_id}[/magenta] updated successfully in application [magenta]{app_id}[/magenta]."
|
|
112
|
+
)
|
|
113
|
+
updated_input_set_dict = updated_input_set.to_dict()
|
|
114
|
+
|
|
115
|
+
if output is not None and output != "":
|
|
116
|
+
with open(output, "w") as f:
|
|
117
|
+
json.dump(updated_input_set_dict, f, indent=2)
|
|
118
|
+
|
|
119
|
+
success(msg=f"Updated input set information saved to [magenta]{output}[/magenta].")
|
|
120
|
+
|
|
121
|
+
return
|
|
122
|
+
|
|
123
|
+
print_json(updated_input_set_dict)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module defines the cloud instance command tree for the Nextmv CLI.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
|
|
7
|
+
from nextmv.cli.cloud.instance.create import app as create_app
|
|
8
|
+
from nextmv.cli.cloud.instance.delete import app as delete_app
|
|
9
|
+
from nextmv.cli.cloud.instance.exists import app as exists_app
|
|
10
|
+
from nextmv.cli.cloud.instance.get import app as get_app
|
|
11
|
+
from nextmv.cli.cloud.instance.list import app as list_app
|
|
12
|
+
from nextmv.cli.cloud.instance.update import app as update_app
|
|
13
|
+
|
|
14
|
+
# Set up subcommand application.
|
|
15
|
+
app = typer.Typer()
|
|
16
|
+
app.add_typer(create_app)
|
|
17
|
+
app.add_typer(delete_app)
|
|
18
|
+
app.add_typer(exists_app)
|
|
19
|
+
app.add_typer(get_app)
|
|
20
|
+
app.add_typer(list_app)
|
|
21
|
+
app.add_typer(update_app)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@app.callback()
|
|
25
|
+
def callback() -> None:
|
|
26
|
+
"""
|
|
27
|
+
Create and manage Nextmv Cloud application instances.
|
|
28
|
+
|
|
29
|
+
An application instance is a representation of a version and optional
|
|
30
|
+
configuration (options/parameters). Instances are the mechanism by which a
|
|
31
|
+
run is made. When you make a new run, the app determines which instance to
|
|
32
|
+
use and then uses the executable code associated to the version for the
|
|
33
|
+
run.
|
|
34
|
+
"""
|
|
35
|
+
pass
|