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,37 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module defines the cloud run command tree for the Nextmv CLI.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
|
|
7
|
+
from nextmv.cli.cloud.run.cancel import app as cancel_app
|
|
8
|
+
from nextmv.cli.cloud.run.create import app as create_app
|
|
9
|
+
from nextmv.cli.cloud.run.get import app as get_app
|
|
10
|
+
from nextmv.cli.cloud.run.input import app as input_app
|
|
11
|
+
from nextmv.cli.cloud.run.list import app as list_app
|
|
12
|
+
from nextmv.cli.cloud.run.logs import app as logs_app
|
|
13
|
+
from nextmv.cli.cloud.run.metadata import app as metadata_app
|
|
14
|
+
from nextmv.cli.cloud.run.track import app as track_app
|
|
15
|
+
|
|
16
|
+
# Set up subcommand application.
|
|
17
|
+
app = typer.Typer()
|
|
18
|
+
app.add_typer(cancel_app)
|
|
19
|
+
app.add_typer(create_app)
|
|
20
|
+
app.add_typer(get_app)
|
|
21
|
+
app.add_typer(input_app)
|
|
22
|
+
app.add_typer(list_app)
|
|
23
|
+
app.add_typer(logs_app)
|
|
24
|
+
app.add_typer(metadata_app)
|
|
25
|
+
app.add_typer(track_app)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@app.callback()
|
|
29
|
+
def callback() -> None:
|
|
30
|
+
"""
|
|
31
|
+
Create and manage Nextmv Cloud application runs.
|
|
32
|
+
|
|
33
|
+
A run represents the execution of a decision model within a Nextmv Cloud
|
|
34
|
+
application. Each run takes an input, processes it using the decision model,
|
|
35
|
+
and produces an output.
|
|
36
|
+
"""
|
|
37
|
+
pass
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module defines the cloud run cancel command for the Nextmv CLI.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
|
|
7
|
+
from nextmv.cli.configuration.config import build_app
|
|
8
|
+
from nextmv.cli.message import in_progress, success
|
|
9
|
+
from nextmv.cli.options import AppIDOption, ProfileOption, RunIDOption
|
|
10
|
+
|
|
11
|
+
# Set up subcommand application.
|
|
12
|
+
app = typer.Typer()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@app.command()
|
|
16
|
+
def cancel(
|
|
17
|
+
app_id: AppIDOption,
|
|
18
|
+
run_id: RunIDOption,
|
|
19
|
+
profile: ProfileOption = None,
|
|
20
|
+
) -> None:
|
|
21
|
+
"""
|
|
22
|
+
Cancel a queued/running Nextmv Cloud application run.
|
|
23
|
+
|
|
24
|
+
[bold][underline]Examples[/underline][/bold]
|
|
25
|
+
|
|
26
|
+
- Cancel the run with ID [magenta]burrow-123[/magenta] belonging to an app with ID [magenta]hare-app[/magenta].
|
|
27
|
+
$ [dim]nextmv cloud run cancel --app-id hare-app --run-id burrow-123[/dim]
|
|
28
|
+
|
|
29
|
+
- Cancel the run with ID [magenta]burrow-123[/magenta] belonging to an app with ID [magenta]hare-app[/magenta].
|
|
30
|
+
Use the profile named [magenta]hare[/magenta].
|
|
31
|
+
$ [dim]nextmv cloud run cancel --app-id hare-app --run-id burrow-123 --profile hare[/dim]
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
35
|
+
in_progress(msg=f"Canceling run [magenta]{run_id}[/magenta]...")
|
|
36
|
+
cloud_app.cancel_run(run_id)
|
|
37
|
+
success(f"Run [magenta]{run_id}[/magenta] canceled.")
|
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module defines the cloud run create command for the Nextmv CLI.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import sys
|
|
7
|
+
import tarfile
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Annotated, Any
|
|
10
|
+
|
|
11
|
+
import typer
|
|
12
|
+
|
|
13
|
+
from nextmv.cli.cloud.run.get import handle_outputs
|
|
14
|
+
from nextmv.cli.cloud.run.logs import handle_logs
|
|
15
|
+
from nextmv.cli.configuration.config import build_app
|
|
16
|
+
from nextmv.cli.message import enum_values, error, print_json, success
|
|
17
|
+
from nextmv.cli.options import AppIDOption, ProfileOption
|
|
18
|
+
from nextmv.cloud.application import Application
|
|
19
|
+
from nextmv.input import InputFormat
|
|
20
|
+
from nextmv.polling import default_polling_options
|
|
21
|
+
from nextmv.run import Format, FormatInput, RunConfiguration, RunQueuing, RunType, RunTypeConfiguration
|
|
22
|
+
|
|
23
|
+
# Set up subcommand application.
|
|
24
|
+
app = typer.Typer()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@app.command()
|
|
28
|
+
def create(
|
|
29
|
+
app_id: AppIDOption,
|
|
30
|
+
# Options for controlling input.
|
|
31
|
+
input: Annotated[
|
|
32
|
+
str | None,
|
|
33
|
+
typer.Option(
|
|
34
|
+
"--input",
|
|
35
|
+
"-i",
|
|
36
|
+
help="The input path to use. File or directory depending on content format. "
|
|
37
|
+
"Uses [magenta]stdin[/magenta] if not defined. "
|
|
38
|
+
"Can be a [magenta].tar.gz[/magenta] file for multi-file content format.",
|
|
39
|
+
metavar="INPUT_PATH",
|
|
40
|
+
rich_help_panel="Input control",
|
|
41
|
+
),
|
|
42
|
+
] = None,
|
|
43
|
+
# Options for controlling output.
|
|
44
|
+
logs: Annotated[
|
|
45
|
+
str | None,
|
|
46
|
+
typer.Option(
|
|
47
|
+
"--logs",
|
|
48
|
+
"-l",
|
|
49
|
+
help="Waits for the run to complete and saves the logs to this location.",
|
|
50
|
+
metavar="LOGS_PATH",
|
|
51
|
+
rich_help_panel="Output control",
|
|
52
|
+
),
|
|
53
|
+
] = None,
|
|
54
|
+
output: Annotated[
|
|
55
|
+
str | None,
|
|
56
|
+
typer.Option(
|
|
57
|
+
"--output",
|
|
58
|
+
"-u",
|
|
59
|
+
help="Waits for the run to complete and save the output to this location. "
|
|
60
|
+
"A file or directory will be created depending on content format. ",
|
|
61
|
+
metavar="OUTPUT_PATH",
|
|
62
|
+
rich_help_panel="Output control",
|
|
63
|
+
),
|
|
64
|
+
] = None,
|
|
65
|
+
tail: Annotated[
|
|
66
|
+
bool,
|
|
67
|
+
typer.Option(
|
|
68
|
+
"--tail",
|
|
69
|
+
"-t",
|
|
70
|
+
help="Tail the logs until the run completes. Logs are streamed to [magenta]stderr[/magenta]. "
|
|
71
|
+
"Specify log output location with --logs.",
|
|
72
|
+
rich_help_panel="Output control",
|
|
73
|
+
),
|
|
74
|
+
] = False,
|
|
75
|
+
wait: Annotated[
|
|
76
|
+
bool,
|
|
77
|
+
typer.Option(
|
|
78
|
+
"--wait",
|
|
79
|
+
"-w",
|
|
80
|
+
help="Wait for the run to complete. Run result is printed to [magenta]stdout[/magenta] for "
|
|
81
|
+
"[magenta]json[/magenta], to a dir for [magenta]multi-file[/magenta]. "
|
|
82
|
+
"Specify output location with --output.",
|
|
83
|
+
rich_help_panel="Output control",
|
|
84
|
+
),
|
|
85
|
+
] = False,
|
|
86
|
+
# Options for run configuration.
|
|
87
|
+
content_format: Annotated[
|
|
88
|
+
InputFormat | None,
|
|
89
|
+
typer.Option(
|
|
90
|
+
"--content-format",
|
|
91
|
+
"-c",
|
|
92
|
+
help=f"The content format of the run to create. Allowed values are: {enum_values(InputFormat)}.",
|
|
93
|
+
metavar="CONTENT_FORMAT",
|
|
94
|
+
rich_help_panel="Run configuration",
|
|
95
|
+
),
|
|
96
|
+
] = None,
|
|
97
|
+
definition_id: Annotated[
|
|
98
|
+
str | None,
|
|
99
|
+
typer.Option(
|
|
100
|
+
"--definition-id",
|
|
101
|
+
"-d",
|
|
102
|
+
help="The definition ID to use for the run. Required for certain run types like ensemble runs.",
|
|
103
|
+
metavar="DEFINITION_ID",
|
|
104
|
+
rich_help_panel="Run configuration",
|
|
105
|
+
),
|
|
106
|
+
] = None,
|
|
107
|
+
description: Annotated[
|
|
108
|
+
str | None,
|
|
109
|
+
typer.Option(
|
|
110
|
+
help="An optional description for the new run.",
|
|
111
|
+
metavar="DESCRIPTION",
|
|
112
|
+
rich_help_panel="Run configuration",
|
|
113
|
+
),
|
|
114
|
+
] = None,
|
|
115
|
+
execution_class: Annotated[
|
|
116
|
+
str | None,
|
|
117
|
+
typer.Option(
|
|
118
|
+
"--execution-class",
|
|
119
|
+
"-e",
|
|
120
|
+
help="The execution class to use for the run, if applicable.",
|
|
121
|
+
metavar="EXECUTION_CLASS",
|
|
122
|
+
rich_help_panel="Run configuration",
|
|
123
|
+
),
|
|
124
|
+
] = None,
|
|
125
|
+
instance_id: Annotated[
|
|
126
|
+
str | None,
|
|
127
|
+
typer.Option(
|
|
128
|
+
help="The instance ID to use for the run.",
|
|
129
|
+
metavar="INSTANCE_ID",
|
|
130
|
+
rich_help_panel="Run configuration",
|
|
131
|
+
),
|
|
132
|
+
] = None,
|
|
133
|
+
integration_id: Annotated[
|
|
134
|
+
str | None,
|
|
135
|
+
typer.Option(
|
|
136
|
+
help="The integration ID to use for the run, if applicable.",
|
|
137
|
+
metavar="INTEGRATION_ID",
|
|
138
|
+
rich_help_panel="Run configuration",
|
|
139
|
+
),
|
|
140
|
+
] = None,
|
|
141
|
+
name: Annotated[
|
|
142
|
+
str | None,
|
|
143
|
+
typer.Option(
|
|
144
|
+
"--name",
|
|
145
|
+
"-n",
|
|
146
|
+
help="An optional name for the new run.",
|
|
147
|
+
metavar="NAME",
|
|
148
|
+
rich_help_panel="Run configuration",
|
|
149
|
+
),
|
|
150
|
+
] = None,
|
|
151
|
+
no_queuing: Annotated[
|
|
152
|
+
bool,
|
|
153
|
+
typer.Option(
|
|
154
|
+
"--no-queuing",
|
|
155
|
+
help="Do not queue run. Default is [magenta]False[/magenta], "
|
|
156
|
+
"meaning the run [italic]will[/italic] be queued.",
|
|
157
|
+
rich_help_panel="Run configuration",
|
|
158
|
+
),
|
|
159
|
+
] = False,
|
|
160
|
+
options: Annotated[
|
|
161
|
+
list[str] | None,
|
|
162
|
+
typer.Option(
|
|
163
|
+
"--options",
|
|
164
|
+
"-o",
|
|
165
|
+
help="Options passed to the run. Format: [magenta]key=value[/magenta]. "
|
|
166
|
+
"Pass multiple options by repeating the flag, or separating with commas.",
|
|
167
|
+
metavar="KEY=VALUE",
|
|
168
|
+
rich_help_panel="Run configuration",
|
|
169
|
+
),
|
|
170
|
+
] = None,
|
|
171
|
+
priority: Annotated[
|
|
172
|
+
int,
|
|
173
|
+
typer.Option(
|
|
174
|
+
help="The priority of the run. Priority is between 1 and 10, with 1 being the highest priority.",
|
|
175
|
+
metavar="PRIORITY",
|
|
176
|
+
rich_help_panel="Run configuration",
|
|
177
|
+
),
|
|
178
|
+
] = 6,
|
|
179
|
+
run_type: Annotated[
|
|
180
|
+
RunType,
|
|
181
|
+
typer.Option(
|
|
182
|
+
"--run-type",
|
|
183
|
+
"-r",
|
|
184
|
+
help=f"The type of run to create. Allowed values are: {enum_values(RunType)}.",
|
|
185
|
+
metavar="RUN_TYPE",
|
|
186
|
+
rich_help_panel="Run configuration",
|
|
187
|
+
),
|
|
188
|
+
] = RunType.STANDARD,
|
|
189
|
+
secret_collection_id: Annotated[
|
|
190
|
+
str | None,
|
|
191
|
+
typer.Option(
|
|
192
|
+
"--secret-collection-id",
|
|
193
|
+
"-s",
|
|
194
|
+
help="The secret collection ID to use for the run, if applicable.",
|
|
195
|
+
metavar="SECRET_COLLECTION_ID",
|
|
196
|
+
rich_help_panel="Run configuration",
|
|
197
|
+
),
|
|
198
|
+
] = None,
|
|
199
|
+
timeout: Annotated[
|
|
200
|
+
int,
|
|
201
|
+
typer.Option(
|
|
202
|
+
help="The maximum time in seconds to wait for results when polling. Poll indefinitely if not set.",
|
|
203
|
+
metavar="TIMEOUT_SECONDS",
|
|
204
|
+
rich_help_panel="Run configuration",
|
|
205
|
+
),
|
|
206
|
+
] = -1,
|
|
207
|
+
profile: ProfileOption = None,
|
|
208
|
+
) -> None:
|
|
209
|
+
"""
|
|
210
|
+
Create a new Nextmv Cloud application run.
|
|
211
|
+
|
|
212
|
+
Input for the run should be given through [magenta]stdin[/magenta] or the
|
|
213
|
+
--input flag. When using the --input flag, the value can be one of the
|
|
214
|
+
following:
|
|
215
|
+
|
|
216
|
+
- [yellow]<FILE_PATH>[/yellow]: path to a [magenta]file[/magenta] containing
|
|
217
|
+
the input data. Use with the [magenta]json[/magenta], and
|
|
218
|
+
[magenta]text[/magenta] content formats.
|
|
219
|
+
- [yellow]<DIR_PATH>[/yellow]: path to a [magenta]directory[/magenta]
|
|
220
|
+
containing the input data files. Use with the
|
|
221
|
+
[magenta]multi-file[/magenta] content format.
|
|
222
|
+
- [yellow]<.tar.gz PATH>[/yellow]: path to a [magenta].tar.gz[/magenta] file
|
|
223
|
+
containing tarred input data files. Use with the
|
|
224
|
+
[magenta]multi-file[/magenta] content format.
|
|
225
|
+
|
|
226
|
+
The CLI determines how to send the input to the application based on the
|
|
227
|
+
value.
|
|
228
|
+
|
|
229
|
+
Use the --wait flag to wait for the run to complete, polling for results.
|
|
230
|
+
Using the --output flag will also activate waiting, and allows you to
|
|
231
|
+
specify a destination (file or dir) for the output, depending on the
|
|
232
|
+
content type.
|
|
233
|
+
|
|
234
|
+
Use the --tail flag to stream logs to [magenta]stderr[/magenta] until the
|
|
235
|
+
run completes. Using the --logs flag will also activate waiting, and allows
|
|
236
|
+
you to specify a file to write the logs to.
|
|
237
|
+
|
|
238
|
+
An application run executes against a specific instance. An instance
|
|
239
|
+
represents the combination of executable code and configuration. You can
|
|
240
|
+
specify the instance with the --instance-id flag. These are the possible
|
|
241
|
+
values for this flag:
|
|
242
|
+
|
|
243
|
+
- [yellow]unspecified[/yellow]: Run against the default instance of the
|
|
244
|
+
application. When an application is created, the default instance is [magenta]latest[/magenta].
|
|
245
|
+
- [yellow]latest[/yellow]: uses the special [magenta]latest[/magenta]
|
|
246
|
+
instance of the application. This corresponds to the latest pushed
|
|
247
|
+
executable.
|
|
248
|
+
- [yellow]<INSTANCE_ID>[/yellow]: uses the instance with the given ID.
|
|
249
|
+
|
|
250
|
+
[bold][underline]Examples[/underline][/bold]
|
|
251
|
+
|
|
252
|
+
- Read a [magenta]json[/magenta] input via [magenta]stdin[/magenta], from an [magenta]input.json[/magenta] file,
|
|
253
|
+
and submit a run to an app with ID [magenta]hare-app[/magenta], using the [magenta]latest[/magenta] instance.
|
|
254
|
+
$ [dim]cat input.json | nextmv cloud run create --app-id hare-app[/dim]
|
|
255
|
+
|
|
256
|
+
- Read a [magenta]json[/magenta] input from an [magenta]input.json[/magenta] file, and
|
|
257
|
+
submit a run to an app with ID [magenta]hare-app[/magenta], using the [magenta]latest[/magenta] instance.
|
|
258
|
+
$ [dim]nextmv cloud run create --app-id hare-app --input input.json[/dim]
|
|
259
|
+
|
|
260
|
+
- Read a [magenta]json[/magenta] input from an [magenta]input.json[/magenta] file, and
|
|
261
|
+
submit a run to an app with ID [magenta]hare-app[/magenta], using the [magenta]latest[/magenta] instance.
|
|
262
|
+
Wait for the run to complete and print the result to [magenta]stdout[/magenta].
|
|
263
|
+
$ [dim]nextmv cloud run create --app-id hare-app --input input.json --wait[/dim]
|
|
264
|
+
|
|
265
|
+
- Read a [magenta]json[/magenta] input from an [magenta]input.json[/magenta] file, and
|
|
266
|
+
submit a run to an app with ID [magenta]hare-app[/magenta], using the [magenta]latest[/magenta] instance.
|
|
267
|
+
Tail the run's logs, streaming to [magenta]stderr[/magenta].
|
|
268
|
+
$ [dim]nextmv cloud run create --app-id hare-app --input input.json --tail[/dim]
|
|
269
|
+
|
|
270
|
+
- Read a [magenta]json[/magenta] input from an [magenta]input.json[/magenta] file, and
|
|
271
|
+
submit a run to an app with ID [magenta]hare-app[/magenta], using the [magenta]latest[/magenta] instance.
|
|
272
|
+
Wait for the run to complete and write the result to an [magenta]output.json[/magenta] file.
|
|
273
|
+
$ [dim]nextmv cloud run create --app-id hare-app --input input.json --output output.json[/dim]
|
|
274
|
+
|
|
275
|
+
- Read a [magenta]json[/magenta] input from an [magenta]input.json[/magenta] file, and
|
|
276
|
+
submit a run to an app with ID [magenta]hare-app[/magenta], using the [magenta]latest[/magenta] instance.
|
|
277
|
+
Wait for the run to complete, and write the logs to a [magenta]logs.log[/magenta] file.
|
|
278
|
+
$ [dim]nextmv cloud run create --app-id hare-app --input input.json --logs logs.log[/dim]
|
|
279
|
+
|
|
280
|
+
- Read a [magenta]json[/magenta] input from an [magenta]input.json[/magenta] file, and submit a run to an app with
|
|
281
|
+
ID [magenta]hare-app[/magenta], using the [magenta]latest[/magenta] instance. Wait for the run to complete. Tail
|
|
282
|
+
the run's logs, streaming to [magenta]stderr[/magenta]. Write the logs to a [magenta]logs.log[/magenta] file.
|
|
283
|
+
Write the result to an [magenta]output.json[/magenta] file.
|
|
284
|
+
$ [dim]nextmv cloud run create --app-id hare-app --input input.json --tail --logs logs.log \\
|
|
285
|
+
--output output.json [/dim]
|
|
286
|
+
|
|
287
|
+
- Read a [magenta]multi-file[/magenta] input from an [magenta]inputs[/magenta] directory, and
|
|
288
|
+
submit a run to an app with ID [magenta]hare-app[/magenta], using the [magenta]default[/magenta] instance.
|
|
289
|
+
$ [dim]nextmv cloud run create --app-id hare-app --input inputs --instance-id default[/dim]
|
|
290
|
+
|
|
291
|
+
- Read a [magenta]multi-file[/magenta] input from an [magenta]inputs[/magenta] directory, and
|
|
292
|
+
submit a run to an app with ID [magenta]hare-app[/magenta], using the [magenta]default[/magenta] instance.
|
|
293
|
+
Wait for the run to complete, and save the results to the default location (a directory named after the run ID).
|
|
294
|
+
$ [dim]nextmv cloud run create --app-id hare-app --input inputs --instance-id default --wait[/dim]
|
|
295
|
+
|
|
296
|
+
- Read a [magenta]multi-file[/magenta] input from an [magenta]inputs[/magenta] directory, and
|
|
297
|
+
submit a run to an app with ID [magenta]hare-app[/magenta], using the [magenta]burrow[/magenta] instance.
|
|
298
|
+
Wait for the run to complete and download the result files to an [magenta]outputs[/magenta] directory.
|
|
299
|
+
$ [dim]nextmv cloud run create --app-id hare-app --input inputs --instance-id burrow --output outputs[/dim]
|
|
300
|
+
"""
|
|
301
|
+
|
|
302
|
+
# Validate that input is provided.
|
|
303
|
+
stdin = sys.stdin.read().strip() if sys.stdin.isatty() is False else None
|
|
304
|
+
if stdin is None and (input is None or input == ""):
|
|
305
|
+
error("Input data must be provided via the --input flag or [magenta]stdin[/magenta].")
|
|
306
|
+
|
|
307
|
+
# Instantiate the basic requirements to start a new run.
|
|
308
|
+
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
309
|
+
config = build_run_config(
|
|
310
|
+
run_type=run_type,
|
|
311
|
+
priority=priority,
|
|
312
|
+
no_queuing=no_queuing,
|
|
313
|
+
execution_class=execution_class,
|
|
314
|
+
content_format=content_format,
|
|
315
|
+
secret_collection_id=secret_collection_id,
|
|
316
|
+
integration_id=integration_id,
|
|
317
|
+
definition_id=definition_id,
|
|
318
|
+
)
|
|
319
|
+
run_options = build_run_options(options)
|
|
320
|
+
|
|
321
|
+
# Start the run before deciding if we should poll or not.
|
|
322
|
+
input_kwarg = resolve_input_kwarg(
|
|
323
|
+
stdin=stdin,
|
|
324
|
+
input=input,
|
|
325
|
+
cloud_app=cloud_app,
|
|
326
|
+
)
|
|
327
|
+
run_id = cloud_app.new_run(
|
|
328
|
+
**input_kwarg,
|
|
329
|
+
instance_id=instance_id,
|
|
330
|
+
name=name,
|
|
331
|
+
description=description,
|
|
332
|
+
options=run_options,
|
|
333
|
+
configuration=config,
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
# If we don't need to poll at all we are done.
|
|
337
|
+
if not wait and not tail and output is None and logs is None:
|
|
338
|
+
print_json({"run_id": run_id})
|
|
339
|
+
|
|
340
|
+
return
|
|
341
|
+
|
|
342
|
+
success(f"Run [magenta]{run_id}[/magenta] created.")
|
|
343
|
+
|
|
344
|
+
# Build the polling options.
|
|
345
|
+
polling_options = default_polling_options()
|
|
346
|
+
polling_options.max_duration = timeout
|
|
347
|
+
|
|
348
|
+
# Handle what happens after the run is created for logging and result
|
|
349
|
+
# retrieval.
|
|
350
|
+
handle_logs(
|
|
351
|
+
cloud_app=cloud_app,
|
|
352
|
+
run_id=run_id,
|
|
353
|
+
tail=tail,
|
|
354
|
+
logs=logs,
|
|
355
|
+
polling_options=polling_options,
|
|
356
|
+
file_output=True,
|
|
357
|
+
)
|
|
358
|
+
handle_outputs(
|
|
359
|
+
cloud_app=cloud_app,
|
|
360
|
+
run_id=run_id,
|
|
361
|
+
wait=wait,
|
|
362
|
+
output=output,
|
|
363
|
+
polling_options=polling_options,
|
|
364
|
+
skip_wait_check=False,
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
def build_run_config(
|
|
369
|
+
run_type: RunType,
|
|
370
|
+
priority: int,
|
|
371
|
+
no_queuing: bool,
|
|
372
|
+
execution_class: str | None = None,
|
|
373
|
+
content_format: InputFormat | None = None,
|
|
374
|
+
secret_collection_id: str | None = None,
|
|
375
|
+
integration_id: str | None = None,
|
|
376
|
+
definition_id: str | None = None,
|
|
377
|
+
) -> RunConfiguration:
|
|
378
|
+
"""
|
|
379
|
+
Builds the run configuration for the new run.
|
|
380
|
+
|
|
381
|
+
Parameters
|
|
382
|
+
----------
|
|
383
|
+
run_type : RunType
|
|
384
|
+
The type of run to create.
|
|
385
|
+
priority : int
|
|
386
|
+
The priority of the run.
|
|
387
|
+
no_queuing : bool
|
|
388
|
+
Whether to disable queuing for the run.
|
|
389
|
+
execution_class : str | None
|
|
390
|
+
The execution class to use for the run, if applicable.
|
|
391
|
+
content_format : InputFormat | None
|
|
392
|
+
The content format of the run to create, if applicable.
|
|
393
|
+
secret_collection_id : str | None
|
|
394
|
+
The secret collection ID to use for the run, if applicable.
|
|
395
|
+
integration_id : str | None
|
|
396
|
+
The integration ID to use for the run, if applicable.
|
|
397
|
+
definition_id : str | None
|
|
398
|
+
The definition ID to use for the run, if applicable.
|
|
399
|
+
|
|
400
|
+
Returns
|
|
401
|
+
-------
|
|
402
|
+
RunConfiguration
|
|
403
|
+
The built run configuration.
|
|
404
|
+
"""
|
|
405
|
+
|
|
406
|
+
config = RunConfiguration(
|
|
407
|
+
run_type=RunTypeConfiguration(
|
|
408
|
+
run_type=RunType(run_type),
|
|
409
|
+
),
|
|
410
|
+
queuing=RunQueuing(
|
|
411
|
+
priority=priority,
|
|
412
|
+
disabled=no_queuing,
|
|
413
|
+
),
|
|
414
|
+
)
|
|
415
|
+
if execution_class is not None:
|
|
416
|
+
config.execution_class = execution_class
|
|
417
|
+
if content_format is not None:
|
|
418
|
+
config.format = Format(
|
|
419
|
+
format_input=FormatInput(
|
|
420
|
+
input_type=InputFormat(content_format),
|
|
421
|
+
),
|
|
422
|
+
)
|
|
423
|
+
if secret_collection_id is not None:
|
|
424
|
+
config.secrets_collection_id = secret_collection_id
|
|
425
|
+
if integration_id is not None:
|
|
426
|
+
config.integration_id = integration_id
|
|
427
|
+
if definition_id is not None:
|
|
428
|
+
config.run_type.definition_id = definition_id
|
|
429
|
+
|
|
430
|
+
return config
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
def build_run_options(options: list[str] | None) -> dict[str, str]:
|
|
434
|
+
"""
|
|
435
|
+
Builds the run options for the new run. One can pass options by either
|
|
436
|
+
using the flag multiple times or by separating with commas in the same
|
|
437
|
+
flag. A combination of both is also possible.
|
|
438
|
+
|
|
439
|
+
Parameters
|
|
440
|
+
----------
|
|
441
|
+
options : list[str] | None
|
|
442
|
+
The list of run options as strings.
|
|
443
|
+
|
|
444
|
+
Returns
|
|
445
|
+
-------
|
|
446
|
+
dict[str, str]
|
|
447
|
+
The built run options.
|
|
448
|
+
"""
|
|
449
|
+
|
|
450
|
+
if options is None:
|
|
451
|
+
return None
|
|
452
|
+
|
|
453
|
+
run_options = {}
|
|
454
|
+
for opt in options:
|
|
455
|
+
# It is possible to pass multiple options separated by commas. The
|
|
456
|
+
# default way though is to use the flag multiple times to specify
|
|
457
|
+
# different options.
|
|
458
|
+
sub_opts = opt.split(",")
|
|
459
|
+
for sub_opt in sub_opts:
|
|
460
|
+
key_value = sub_opt.split("=", 1)
|
|
461
|
+
if len(key_value) != 2:
|
|
462
|
+
error(f"Invalid option format: {sub_opt}. Expected format is [magenta]key=value[/magenta].")
|
|
463
|
+
|
|
464
|
+
key, value = key_value
|
|
465
|
+
run_options[key] = value
|
|
466
|
+
|
|
467
|
+
return run_options
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
def resolve_input_kwarg(
|
|
471
|
+
stdin: str | None,
|
|
472
|
+
input: str | None,
|
|
473
|
+
cloud_app: Application,
|
|
474
|
+
) -> dict[str, Any]:
|
|
475
|
+
"""
|
|
476
|
+
Gets the keyword argument related to the input that is needed for the run
|
|
477
|
+
creation. It handles stdin, file, and directory inputs. It uploads the
|
|
478
|
+
input to the cloud application if needed.
|
|
479
|
+
|
|
480
|
+
Parameters
|
|
481
|
+
----------
|
|
482
|
+
stdin : str | None
|
|
483
|
+
The stdin input data, if provided.
|
|
484
|
+
input : str | None
|
|
485
|
+
The input path, if provided.
|
|
486
|
+
cloud_app : Application
|
|
487
|
+
The cloud application instance.
|
|
488
|
+
|
|
489
|
+
Returns
|
|
490
|
+
-------
|
|
491
|
+
dict[str, Any]
|
|
492
|
+
The keyword argument with the resolved input.
|
|
493
|
+
"""
|
|
494
|
+
|
|
495
|
+
if stdin is not None:
|
|
496
|
+
# Handle the case where stdin is provided as JSON for a JSON app.
|
|
497
|
+
try:
|
|
498
|
+
input_data = json.loads(stdin)
|
|
499
|
+
except json.JSONDecodeError:
|
|
500
|
+
input_data = stdin
|
|
501
|
+
|
|
502
|
+
return {"input": input_data}
|
|
503
|
+
|
|
504
|
+
input_path = Path(input)
|
|
505
|
+
|
|
506
|
+
# If the input is a file, we need to determine if it is a tar file or
|
|
507
|
+
# a regular file and upload it accordingly. If it is a regular file, we
|
|
508
|
+
# need to read its content.
|
|
509
|
+
if input_path.is_file():
|
|
510
|
+
upload_url = cloud_app.upload_url()
|
|
511
|
+
if tarfile.is_tarfile(input_path):
|
|
512
|
+
cloud_app.upload_data(data=None, upload_url=upload_url, tar_file=input_path)
|
|
513
|
+
else:
|
|
514
|
+
input_data = input_path.read_text()
|
|
515
|
+
cloud_app.upload_data(data=input_data, upload_url=upload_url)
|
|
516
|
+
|
|
517
|
+
return {"upload_id": upload_url.upload_id}
|
|
518
|
+
|
|
519
|
+
# If the input is a directory, we give the path directly to the run method.
|
|
520
|
+
# Internally, the files will be tarred and uploaded.
|
|
521
|
+
if input_path.is_dir():
|
|
522
|
+
return {"input_dir_path": input}
|
|
523
|
+
|
|
524
|
+
error(f"Input path [magenta]{input}[/magenta] does not exist.")
|