nextmv 0.40.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/__init__.py +2 -0
- nextmv/cli/CONTRIBUTING.md +511 -0
- nextmv/cli/cloud/__init__.py +45 -0
- nextmv/cli/cloud/acceptance/__init__.py +27 -0
- nextmv/cli/cloud/acceptance/create.py +393 -0
- nextmv/cli/cloud/acceptance/delete.py +68 -0
- nextmv/cli/cloud/acceptance/get.py +104 -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 +60 -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 +141 -0
- nextmv/cli/cloud/app/delete.py +58 -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 +137 -0
- nextmv/cli/cloud/app/update.py +124 -0
- nextmv/cli/cloud/batch/__init__.py +29 -0
- nextmv/cli/cloud/batch/create.py +454 -0
- nextmv/cli/cloud/batch/delete.py +68 -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 +31 -0
- nextmv/cli/cloud/ensemble/create.py +414 -0
- nextmv/cli/cloud/ensemble/delete.py +67 -0
- nextmv/cli/cloud/ensemble/get.py +65 -0
- nextmv/cli/cloud/ensemble/update.py +103 -0
- nextmv/cli/cloud/input_set/__init__.py +30 -0
- nextmv/cli/cloud/input_set/create.py +168 -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 +290 -0
- nextmv/cli/cloud/instance/delete.py +62 -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 +146 -0
- nextmv/cli/cloud/managed_input/delete.py +65 -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 +530 -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 +167 -0
- nextmv/cli/cloud/run/metadata.py +67 -0
- nextmv/cli/cloud/run/track.py +501 -0
- nextmv/cli/cloud/scenario/__init__.py +29 -0
- nextmv/cli/cloud/scenario/create.py +451 -0
- nextmv/cli/cloud/scenario/delete.py +65 -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 +67 -0
- nextmv/cli/cloud/secrets/get.py +66 -0
- nextmv/cli/cloud/secrets/list.py +60 -0
- nextmv/cli/cloud/secrets/update.py +147 -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 +97 -0
- nextmv/cli/cloud/version/delete.py +62 -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 +3 -3
- nextmv/cli/community/list.py +1 -1
- nextmv/cli/configuration/__init__.py +23 -0
- nextmv/cli/configuration/config.py +68 -4
- nextmv/cli/configuration/create.py +14 -15
- nextmv/cli/configuration/delete.py +24 -12
- nextmv/cli/configuration/list.py +1 -1
- nextmv/cli/main.py +58 -16
- nextmv/cli/message.py +153 -0
- nextmv/cli/options.py +168 -0
- nextmv/cli/version.py +20 -1
- nextmv/cloud/__init__.py +4 -1
- nextmv/cloud/acceptance_test.py +19 -18
- nextmv/cloud/account.py +268 -24
- nextmv/cloud/application/__init__.py +955 -0
- nextmv/cloud/application/_acceptance.py +419 -0
- nextmv/cloud/application/_batch_scenario.py +860 -0
- nextmv/cloud/application/_ensemble.py +251 -0
- nextmv/cloud/application/_input_set.py +227 -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/_utils.py +54 -0
- nextmv/cloud/application/_version.py +303 -0
- nextmv/cloud/batch_experiment.py +3 -1
- nextmv/cloud/instance.py +11 -1
- nextmv/cloud/integration.py +1 -1
- nextmv/cloud/package.py +50 -9
- nextmv/input.py +20 -36
- nextmv/local/application.py +3 -15
- nextmv/polling.py +54 -16
- nextmv/run.py +83 -27
- {nextmv-0.40.0.dist-info → nextmv-1.0.0.dev0.dist-info}/METADATA +33 -8
- nextmv-1.0.0.dev0.dist-info/RECORD +158 -0
- nextmv/cli/community/community.py +0 -24
- nextmv/cli/configuration/configuration.py +0 -23
- nextmv/cli/error.py +0 -22
- nextmv/cloud/application.py +0 -4204
- nextmv-0.40.0.dist-info/RECORD +0 -66
- {nextmv-0.40.0.dist-info → nextmv-1.0.0.dev0.dist-info}/WHEEL +0 -0
- {nextmv-0.40.0.dist-info → nextmv-1.0.0.dev0.dist-info}/licenses/LICENSE +0 -0
nextmv/cli/options.py
CHANGED
|
@@ -22,3 +22,171 @@ ProfileOption = Annotated[
|
|
|
22
22
|
metavar="PROFILE_NAME",
|
|
23
23
|
),
|
|
24
24
|
]
|
|
25
|
+
|
|
26
|
+
# app_id option - can be used in any command that requires an application ID.
|
|
27
|
+
# Define it as follows in commands or callbacks, as necessary:
|
|
28
|
+
# app_id: AppIDOption
|
|
29
|
+
AppIDOption = Annotated[
|
|
30
|
+
str,
|
|
31
|
+
typer.Option(
|
|
32
|
+
"--app-id",
|
|
33
|
+
"-a",
|
|
34
|
+
help="The Nextmv Cloud application ID to use for this action.",
|
|
35
|
+
envvar="NEXTMV_APP_ID",
|
|
36
|
+
metavar="APP_ID",
|
|
37
|
+
),
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
# run_id option - can be used in any command that requires a run ID.
|
|
41
|
+
# Define it as follows in commands or callbacks, as necessary:
|
|
42
|
+
# run_id: RunIDOption
|
|
43
|
+
RunIDOption = Annotated[
|
|
44
|
+
str,
|
|
45
|
+
typer.Option(
|
|
46
|
+
"--run-id",
|
|
47
|
+
"-r",
|
|
48
|
+
help="The Nextmv Cloud run ID to use for this action.",
|
|
49
|
+
envvar="NEXTMV_RUN_ID",
|
|
50
|
+
metavar="RUN_ID",
|
|
51
|
+
),
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
# version_id option - can be used in any command that requires a version ID.
|
|
55
|
+
# Define it as follows in commands or callbacks, as necessary:
|
|
56
|
+
# version_id: VersionIDOption
|
|
57
|
+
VersionIDOption = Annotated[
|
|
58
|
+
str,
|
|
59
|
+
typer.Option(
|
|
60
|
+
"--version-id",
|
|
61
|
+
"-v",
|
|
62
|
+
help="The Nextmv Cloud version ID to use for this action.",
|
|
63
|
+
envvar="NEXTMV_VERSION_ID",
|
|
64
|
+
metavar="VERSION_ID",
|
|
65
|
+
),
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
# input_set_id option - can be used in any command that requires an input set ID.
|
|
69
|
+
# Define it as follows in commands or callbacks, as necessary:
|
|
70
|
+
# input_set_id: InputSetIDOption
|
|
71
|
+
InputSetIDOption = Annotated[
|
|
72
|
+
str,
|
|
73
|
+
typer.Option(
|
|
74
|
+
"--input-set-id",
|
|
75
|
+
"-s",
|
|
76
|
+
help="The Nextmv Cloud input set ID to use for this action.",
|
|
77
|
+
envvar="NEXTMV_INPUT_SET_ID",
|
|
78
|
+
metavar="INPUT_SET_ID",
|
|
79
|
+
),
|
|
80
|
+
]
|
|
81
|
+
|
|
82
|
+
# instance_id option - can be used in any command that requires an instance ID.
|
|
83
|
+
# Define it as follows in commands or callbacks, as necessary:
|
|
84
|
+
# instance_id: InstanceIDOption
|
|
85
|
+
InstanceIDOption = Annotated[
|
|
86
|
+
str,
|
|
87
|
+
typer.Option(
|
|
88
|
+
"--instance-id",
|
|
89
|
+
"-i",
|
|
90
|
+
help="The Nextmv Cloud instance ID to use for this action.",
|
|
91
|
+
envvar="NEXTMV_INSTANCE_ID",
|
|
92
|
+
metavar="INSTANCE_ID",
|
|
93
|
+
),
|
|
94
|
+
]
|
|
95
|
+
|
|
96
|
+
# managed_input_id option - can be used in any command that requires a managed input ID.
|
|
97
|
+
# Define it as follows in commands or callbacks, as necessary:
|
|
98
|
+
# managed_input_id: ManagedInputIDOption
|
|
99
|
+
ManagedInputIDOption = Annotated[
|
|
100
|
+
str,
|
|
101
|
+
typer.Option(
|
|
102
|
+
"--managed-input-id",
|
|
103
|
+
"-m",
|
|
104
|
+
help="The Nextmv Cloud managed input ID to use for this action.",
|
|
105
|
+
envvar="NEXTMV_MANAGED_INPUT_ID",
|
|
106
|
+
metavar="MANAGED_INPUT_ID",
|
|
107
|
+
),
|
|
108
|
+
]
|
|
109
|
+
|
|
110
|
+
# ensemble_definition_id option - can be used in any command that requires an ensemble definition ID.
|
|
111
|
+
# Define it as follows in commands or callbacks, as necessary:
|
|
112
|
+
# ensemble_definition_id: EnsembleDefinitionIDOption
|
|
113
|
+
EnsembleDefinitionIDOption = Annotated[
|
|
114
|
+
str,
|
|
115
|
+
typer.Option(
|
|
116
|
+
"--ensemble-definition-id",
|
|
117
|
+
"-e",
|
|
118
|
+
help="The Nextmv Cloud ensemble definition ID to use for this action.",
|
|
119
|
+
envvar="NEXTMV_ENSEMBLE_DEFINITION_ID",
|
|
120
|
+
metavar="ENSEMBLE_DEFINITION_ID",
|
|
121
|
+
),
|
|
122
|
+
]
|
|
123
|
+
|
|
124
|
+
# account_id option - can be used in any command that requires an account ID.
|
|
125
|
+
# Define it as follows in commands or callbacks, as necessary:
|
|
126
|
+
# account_id: AccountIDOption
|
|
127
|
+
AccountIDOption = Annotated[
|
|
128
|
+
str,
|
|
129
|
+
typer.Option(
|
|
130
|
+
"--account-id",
|
|
131
|
+
"-a",
|
|
132
|
+
help="The Nextmv Cloud account ID to use for this action.",
|
|
133
|
+
envvar="NEXTMV_ACCOUNT_ID",
|
|
134
|
+
metavar="ACCOUNT_ID",
|
|
135
|
+
),
|
|
136
|
+
]
|
|
137
|
+
|
|
138
|
+
# acceptance_test_id option - can be used in any command that requires an acceptance test ID.
|
|
139
|
+
# Define it as follows in commands or callbacks, as necessary:
|
|
140
|
+
# acceptance_test_id: AcceptanceTestIDOption
|
|
141
|
+
AcceptanceTestIDOption = Annotated[
|
|
142
|
+
str,
|
|
143
|
+
typer.Option(
|
|
144
|
+
"--acceptance-test-id",
|
|
145
|
+
"-t",
|
|
146
|
+
help="The Nextmv Cloud acceptance test ID to use for this action.",
|
|
147
|
+
envvar="NEXTMV_ACCEPTANCE_TEST_ID",
|
|
148
|
+
metavar="ACCEPTANCE_TEST_ID",
|
|
149
|
+
),
|
|
150
|
+
]
|
|
151
|
+
|
|
152
|
+
# batch_experiment_id option - can be used in any command that requires a batch experiment ID.
|
|
153
|
+
# Define it as follows in commands or callbacks, as necessary:
|
|
154
|
+
# batch_experiment_id: BatchExperimentIDOption
|
|
155
|
+
BatchExperimentIDOption = Annotated[
|
|
156
|
+
str,
|
|
157
|
+
typer.Option(
|
|
158
|
+
"--batch-experiment-id",
|
|
159
|
+
"-b",
|
|
160
|
+
help="The Nextmv Cloud batch experiment ID to use for this action.",
|
|
161
|
+
envvar="NEXTMV_BATCH_EXPERIMENT_ID",
|
|
162
|
+
metavar="BATCH_EXPERIMENT_ID",
|
|
163
|
+
),
|
|
164
|
+
]
|
|
165
|
+
|
|
166
|
+
# scenario_test_id option - can be used in any command that requires a scenario test ID.
|
|
167
|
+
# Define it as follows in commands or callbacks, as necessary:
|
|
168
|
+
# scenario_test_id: ScenarioTestIDOption
|
|
169
|
+
ScenarioTestIDOption = Annotated[
|
|
170
|
+
str,
|
|
171
|
+
typer.Option(
|
|
172
|
+
"--scenario-test-id",
|
|
173
|
+
"-i",
|
|
174
|
+
help="The Nextmv Cloud scenario test ID to use for this action.",
|
|
175
|
+
envvar="NEXTMV_SCENARIO_TEST_ID",
|
|
176
|
+
metavar="SCENARIO_TEST_ID",
|
|
177
|
+
),
|
|
178
|
+
]
|
|
179
|
+
|
|
180
|
+
# secrets_collection_id option - can be used in any command that requires a secrets collection ID.
|
|
181
|
+
# Define it as follows in commands or callbacks, as necessary:
|
|
182
|
+
# secrets_collection_id: SecretsCollectionIDOption
|
|
183
|
+
SecretsCollectionIDOption = Annotated[
|
|
184
|
+
str,
|
|
185
|
+
typer.Option(
|
|
186
|
+
"--secrets-collection-id",
|
|
187
|
+
"-s",
|
|
188
|
+
help="The Nextmv Cloud secrets collection ID to use for this action.",
|
|
189
|
+
envvar="NEXTMV_SECRETS_COLLECTION_ID",
|
|
190
|
+
metavar="SECRETS_COLLECTION_ID",
|
|
191
|
+
),
|
|
192
|
+
]
|
nextmv/cli/version.py
CHANGED
|
@@ -14,6 +14,25 @@ app = typer.Typer()
|
|
|
14
14
|
def version() -> None:
|
|
15
15
|
"""
|
|
16
16
|
Show the current version of the Nextmv CLI.
|
|
17
|
+
|
|
18
|
+
[bold][underline]Examples[/underline][/bold]
|
|
19
|
+
|
|
20
|
+
- Show the version.
|
|
21
|
+
$ [green]nextmv version[/green]
|
|
17
22
|
"""
|
|
18
23
|
|
|
19
|
-
|
|
24
|
+
version_callback(True)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def version_callback(value: bool):
|
|
28
|
+
"""
|
|
29
|
+
Callback function to display the version.
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
value : bool
|
|
34
|
+
If True, print the version and exit.
|
|
35
|
+
"""
|
|
36
|
+
if value:
|
|
37
|
+
print(__version__)
|
|
38
|
+
raise typer.Exit()
|
nextmv/cloud/__init__.py
CHANGED
|
@@ -15,6 +15,7 @@ from nextmv.manifest import ManifestPythonModel as ManifestPythonModel
|
|
|
15
15
|
from nextmv.manifest import ManifestRuntime as ManifestRuntime
|
|
16
16
|
from nextmv.manifest import ManifestType as ManifestType
|
|
17
17
|
from nextmv.polling import PollingOptions as PollingOptions
|
|
18
|
+
from nextmv.polling import poll as poll
|
|
18
19
|
from nextmv.run import ErrorLog as ErrorLog
|
|
19
20
|
from nextmv.run import ExternalRunResult as ExternalRunResult
|
|
20
21
|
from nextmv.run import Format as Format
|
|
@@ -53,10 +54,12 @@ from .acceptance_test import ResultStatistics as ResultStatistics
|
|
|
53
54
|
from .acceptance_test import StatisticType as StatisticType
|
|
54
55
|
from .acceptance_test import ToleranceType as ToleranceType
|
|
55
56
|
from .account import Account as Account
|
|
57
|
+
from .account import AccountMember as AccountMember
|
|
56
58
|
from .account import Queue as Queue
|
|
57
59
|
from .account import QueuedRun as QueuedRun
|
|
58
60
|
from .application import Application as Application
|
|
59
|
-
from .application import
|
|
61
|
+
from .application import ApplicationType as ApplicationType
|
|
62
|
+
from .application import list_applications as list_applications
|
|
60
63
|
from .assets import RunAsset as RunAsset
|
|
61
64
|
from .batch_experiment import BatchExperiment as BatchExperiment
|
|
62
65
|
from .batch_experiment import BatchExperimentInformation as BatchExperimentInformation
|
nextmv/cloud/acceptance_test.py
CHANGED
|
@@ -888,20 +888,20 @@ class AcceptanceTest(BaseModel):
|
|
|
888
888
|
Name of the acceptance test.
|
|
889
889
|
description : str
|
|
890
890
|
Description of the acceptance test.
|
|
891
|
-
|
|
891
|
+
created_at : datetime
|
|
892
|
+
Creation date of the acceptance test.
|
|
893
|
+
updated_at : datetime
|
|
894
|
+
Last update date of the acceptance test.
|
|
895
|
+
app_id : str, optional
|
|
892
896
|
ID of the app that owns the acceptance test.
|
|
893
|
-
experiment_id : str
|
|
897
|
+
experiment_id : str, optional
|
|
894
898
|
ID of the batch experiment underlying the acceptance test.
|
|
895
|
-
control : ComparisonInstance
|
|
899
|
+
control : ComparisonInstance, optional
|
|
896
900
|
Control instance of the acceptance test.
|
|
897
|
-
candidate : ComparisonInstance
|
|
901
|
+
candidate : ComparisonInstance, optional
|
|
898
902
|
Candidate instance of the acceptance test.
|
|
899
|
-
metrics : list[Metric]
|
|
903
|
+
metrics : list[Metric], optional
|
|
900
904
|
Metrics to evaluate in the acceptance test.
|
|
901
|
-
created_at : datetime
|
|
902
|
-
Creation date of the acceptance test.
|
|
903
|
-
updated_at : datetime
|
|
904
|
-
Last update date of the acceptance test.
|
|
905
905
|
status : ExperimentStatus, optional
|
|
906
906
|
Status of the acceptance test.
|
|
907
907
|
results : AcceptanceTestResults, optional
|
|
@@ -942,20 +942,21 @@ class AcceptanceTest(BaseModel):
|
|
|
942
942
|
"""Name of the acceptance test."""
|
|
943
943
|
description: str
|
|
944
944
|
"""Description of the acceptance test."""
|
|
945
|
-
|
|
945
|
+
created_at: datetime
|
|
946
|
+
"""Creation date of the acceptance test."""
|
|
947
|
+
updated_at: datetime
|
|
948
|
+
"""Last update date of the acceptance test."""
|
|
949
|
+
|
|
950
|
+
app_id: str | None = None
|
|
946
951
|
"""ID of the app that owns the acceptance test."""
|
|
947
|
-
experiment_id: str
|
|
952
|
+
experiment_id: str | None = None
|
|
948
953
|
"""ID of the batch experiment underlying in the acceptance test."""
|
|
949
|
-
control: ComparisonInstance
|
|
954
|
+
control: ComparisonInstance | None = None
|
|
950
955
|
"""Control instance of the acceptance test."""
|
|
951
|
-
candidate: ComparisonInstance
|
|
956
|
+
candidate: ComparisonInstance | None = None
|
|
952
957
|
"""Candidate instance of the acceptance test."""
|
|
953
|
-
metrics: list[Metric]
|
|
958
|
+
metrics: list[Metric] | None = None
|
|
954
959
|
"""Metrics of the acceptance test."""
|
|
955
|
-
created_at: datetime
|
|
956
|
-
"""Creation date of the acceptance test."""
|
|
957
|
-
updated_at: datetime
|
|
958
|
-
"""Last update date of the acceptance test."""
|
|
959
960
|
status: ExperimentStatus | None = ExperimentStatus.UNKNOWN
|
|
960
961
|
"""Status of the acceptance test."""
|
|
961
962
|
results: AcceptanceTestResults | None = None
|
nextmv/cloud/account.py
CHANGED
|
@@ -15,16 +15,18 @@ Account
|
|
|
15
15
|
The Nextmv Platform account with API access methods.
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
|
-
from dataclasses import dataclass
|
|
19
18
|
from datetime import datetime
|
|
20
19
|
|
|
20
|
+
from pydantic import AliasChoices, Field
|
|
21
|
+
|
|
21
22
|
from nextmv.base_model import BaseModel
|
|
22
23
|
from nextmv.cloud.client import Client
|
|
23
24
|
from nextmv.status import Status, StatusV2
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
class QueuedRun(BaseModel):
|
|
27
|
-
"""
|
|
28
|
+
"""
|
|
29
|
+
A run that is pending to be executed in the account.
|
|
28
30
|
|
|
29
31
|
You can import the `QueuedRun` class directly from `cloud`:
|
|
30
32
|
|
|
@@ -104,7 +106,8 @@ class QueuedRun(BaseModel):
|
|
|
104
106
|
|
|
105
107
|
|
|
106
108
|
class Queue(BaseModel):
|
|
107
|
-
"""
|
|
109
|
+
"""
|
|
110
|
+
A queue is a list of runs that are pending to be executed, or currently
|
|
108
111
|
being executed, in the account.
|
|
109
112
|
|
|
110
113
|
You can import the `Queue` class directly from `cloud`:
|
|
@@ -123,7 +126,9 @@ class Queue(BaseModel):
|
|
|
123
126
|
|
|
124
127
|
Examples
|
|
125
128
|
--------
|
|
126
|
-
>>>
|
|
129
|
+
>>> from nextmv.cloud import Client, Account
|
|
130
|
+
>>> client = Client(api_key="your-api-key")
|
|
131
|
+
>>> account = Account.get(client=client, account_id="your-account-id")
|
|
127
132
|
>>> queue = account.queue()
|
|
128
133
|
>>> print(f"Number of runs in queue: {len(queue.runs)}")
|
|
129
134
|
Number of runs in queue: 5
|
|
@@ -137,9 +142,54 @@ class Queue(BaseModel):
|
|
|
137
142
|
"""List of runs in the queue."""
|
|
138
143
|
|
|
139
144
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
145
|
+
class AccountMember(BaseModel):
|
|
146
|
+
"""
|
|
147
|
+
A member of a Nextmv Cloud account (organization).
|
|
148
|
+
|
|
149
|
+
You can import the `AccountMember` class directly from `cloud`:
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
from nextmv.cloud import AccountMember
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Represents an individual member of an organization in Nextmv Cloud,
|
|
156
|
+
including their role and invitation status.
|
|
157
|
+
|
|
158
|
+
Attributes
|
|
159
|
+
----------
|
|
160
|
+
email : str | None
|
|
161
|
+
Email of the account member.
|
|
162
|
+
role : str | None
|
|
163
|
+
Role of the account member.
|
|
164
|
+
pending_invite : bool | None
|
|
165
|
+
Whether the member has a pending invite.
|
|
166
|
+
|
|
167
|
+
Examples
|
|
168
|
+
--------
|
|
169
|
+
>>> member = AccountMember.from_dict({
|
|
170
|
+
... "email": "peter.rabbit@carrotexpress.com",
|
|
171
|
+
... "role": "admin",
|
|
172
|
+
... "pending_invite": False
|
|
173
|
+
... })
|
|
174
|
+
>>> print(f"{member.email} - {member.role}")
|
|
175
|
+
peter.rabbit@carrotexpress.com - admin
|
|
176
|
+
"""
|
|
177
|
+
|
|
178
|
+
email: str | None = None
|
|
179
|
+
"""Email of the account member."""
|
|
180
|
+
role: str | None = None
|
|
181
|
+
"""Role of the account member."""
|
|
182
|
+
pending_invite: bool | None = None
|
|
183
|
+
"""Whether the member has a pending invite."""
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class Account(BaseModel):
|
|
187
|
+
"""
|
|
188
|
+
The Nextmv Cloud account (organization).
|
|
189
|
+
|
|
190
|
+
To handle managed accounts, SSO must be configured for your organization.
|
|
191
|
+
Please contact [Nextmv support](https://www.nextmv.io/contact) for
|
|
192
|
+
assistance.
|
|
143
193
|
|
|
144
194
|
You can import the `Account` class directly from `cloud`:
|
|
145
195
|
|
|
@@ -147,41 +197,191 @@ class Account:
|
|
|
147
197
|
from nextmv.cloud import Account
|
|
148
198
|
```
|
|
149
199
|
|
|
150
|
-
This class provides access to account-level operations in the Nextmv
|
|
200
|
+
This class provides access to account-level operations in the Nextmv Cloud,
|
|
151
201
|
such as retrieving the queue of runs.
|
|
152
202
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
client : Client
|
|
156
|
-
Client to use for interacting with the Nextmv Cloud API.
|
|
157
|
-
endpoint : str, optional
|
|
158
|
-
Base endpoint for the account, by default "v1/account"
|
|
203
|
+
Note: It is recommended to use `Account.get()` or `Account.new()`
|
|
204
|
+
instead of direct initialization to ensure proper setup.
|
|
159
205
|
|
|
160
|
-
|
|
206
|
+
Parameters
|
|
161
207
|
----------
|
|
162
208
|
client : Client
|
|
163
209
|
Client to use for interacting with the Nextmv Cloud API.
|
|
164
|
-
|
|
165
|
-
|
|
210
|
+
account_id : str, optional
|
|
211
|
+
ID of the account (organization).
|
|
212
|
+
name : str, optional
|
|
213
|
+
Name of the account (organization).
|
|
214
|
+
members : list[AccountMember], optional
|
|
215
|
+
List of members in the account (organization).
|
|
216
|
+
account_endpoint : str, default="v1/account"
|
|
217
|
+
Base endpoint for the account (SDK-specific).
|
|
218
|
+
organization_endpoint : str, default="v1/organization/{organization_id}"
|
|
219
|
+
Base endpoint for organization operations (SDK-specific).
|
|
166
220
|
|
|
167
221
|
Examples
|
|
168
222
|
--------
|
|
169
223
|
>>> from nextmv.cloud import Client, Account
|
|
170
224
|
>>> client = Client(api_key="your-api-key")
|
|
171
|
-
>>>
|
|
225
|
+
>>> # Retrieve an existing account
|
|
226
|
+
>>> account = Account.get(client=client, account_id="your-account-id")
|
|
227
|
+
>>> print(f"Account name: {account.name}")
|
|
228
|
+
Account name: Bunny Logistics
|
|
229
|
+
>>> # Create a new account
|
|
230
|
+
>>> new_account = Account.new(client=client, name="Hare Delivery Co", admins=["admin@example.com"])
|
|
231
|
+
>>> # Get the queue of runs
|
|
172
232
|
>>> queue = account.queue()
|
|
173
233
|
>>> print(f"Number of runs in queue: {len(queue.runs)}")
|
|
174
234
|
Number of runs in queue: 3
|
|
175
235
|
"""
|
|
176
236
|
|
|
177
|
-
|
|
237
|
+
# Actual API attributes of an account.
|
|
238
|
+
account_id: str | None = Field(
|
|
239
|
+
serialization_alias="id",
|
|
240
|
+
validation_alias=AliasChoices("id", "account_id"),
|
|
241
|
+
default=None,
|
|
242
|
+
)
|
|
243
|
+
"""ID of the account (organization)."""
|
|
244
|
+
name: str | None = None
|
|
245
|
+
"""Name of the account (organization)."""
|
|
246
|
+
members: list[AccountMember] | None = None
|
|
247
|
+
"""List of members in the account (organization)."""
|
|
248
|
+
|
|
249
|
+
# SDK-specific attributes for convenience when using methods.
|
|
250
|
+
client: Client = Field(exclude=True)
|
|
178
251
|
"""Client to use for interacting with the Nextmv Cloud API."""
|
|
179
|
-
|
|
180
|
-
endpoint: str = "v1/account"
|
|
252
|
+
account_endpoint: str = Field(exclude=True, default="v1/account")
|
|
181
253
|
"""Base endpoint for the account."""
|
|
254
|
+
organization_endpoint: str = Field(exclude=True, default="v1/organization/{organization_id}")
|
|
255
|
+
|
|
256
|
+
def model_post_init(self, __context) -> None:
|
|
257
|
+
"""
|
|
258
|
+
Initialize the organization_endpoint attribute.
|
|
259
|
+
|
|
260
|
+
This method is automatically called after class initialization to
|
|
261
|
+
format the organization_endpoint URL with the account ID.
|
|
262
|
+
"""
|
|
263
|
+
|
|
264
|
+
self.organization_endpoint = self.organization_endpoint.format(organization_id=self.account_id)
|
|
265
|
+
|
|
266
|
+
@classmethod
|
|
267
|
+
def get(cls, client: Client, account_id: str) -> "Account":
|
|
268
|
+
"""
|
|
269
|
+
Retrieve an account directly from Nextmv Cloud.
|
|
270
|
+
|
|
271
|
+
This function is useful if you want to populate an `Account` class
|
|
272
|
+
by fetching the attributes directly from Nextmv Cloud.
|
|
273
|
+
|
|
274
|
+
Parameters
|
|
275
|
+
----------
|
|
276
|
+
client : Client
|
|
277
|
+
Client to use for interacting with the Nextmv Cloud API.
|
|
278
|
+
account_id : str
|
|
279
|
+
ID of the account to retrieve.
|
|
280
|
+
|
|
281
|
+
Returns
|
|
282
|
+
-------
|
|
283
|
+
Account
|
|
284
|
+
The requested account.
|
|
285
|
+
|
|
286
|
+
Raises
|
|
287
|
+
------
|
|
288
|
+
requests.HTTPError
|
|
289
|
+
If the response status code is not 2xx.
|
|
290
|
+
|
|
291
|
+
Examples
|
|
292
|
+
--------
|
|
293
|
+
>>> from nextmv.cloud import Client, Account
|
|
294
|
+
>>> client = Client(api_key="your-api-key")
|
|
295
|
+
>>> account = Account.get(client=client, account_id="bunny-logistics")
|
|
296
|
+
>>> print(f"Account: {account.name}")
|
|
297
|
+
Account: Bunny Logistics
|
|
298
|
+
>>> print(f"Members: {len(account.members)}")
|
|
299
|
+
Members: 3
|
|
300
|
+
"""
|
|
301
|
+
|
|
302
|
+
response = client.request(
|
|
303
|
+
method="GET",
|
|
304
|
+
endpoint=f"v1/organization/{account_id}",
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
return cls.from_dict({"client": client} | response.json())
|
|
308
|
+
|
|
309
|
+
@classmethod
|
|
310
|
+
def new(
|
|
311
|
+
cls,
|
|
312
|
+
client: Client,
|
|
313
|
+
name: str,
|
|
314
|
+
admins: list[str],
|
|
315
|
+
) -> "Account":
|
|
316
|
+
"""
|
|
317
|
+
Create a new account (organization) directly in Nextmv Cloud.
|
|
318
|
+
|
|
319
|
+
To create managed accounts, SSO must be configured for your
|
|
320
|
+
organization. Please contact [Nextmv
|
|
321
|
+
support](https://www.nextmv.io/contact) for assistance.
|
|
322
|
+
|
|
323
|
+
Parameters
|
|
324
|
+
----------
|
|
325
|
+
client : Client
|
|
326
|
+
Client to use for interacting with the Nextmv Cloud API.
|
|
327
|
+
name : str
|
|
328
|
+
Name of the new account.
|
|
329
|
+
admins : list[str]
|
|
330
|
+
List of admin user emails for the new account.
|
|
331
|
+
|
|
332
|
+
Returns
|
|
333
|
+
-------
|
|
334
|
+
Account
|
|
335
|
+
The newly created account.
|
|
336
|
+
|
|
337
|
+
Examples
|
|
338
|
+
--------
|
|
339
|
+
>>> from nextmv.cloud import Client
|
|
340
|
+
>>> client = Client(api_key="your-api-key")
|
|
341
|
+
>>> account = Account.new(client=client, name="My New Account", admins=["admin@example.com"])
|
|
342
|
+
"""
|
|
343
|
+
|
|
344
|
+
if len(admins) == 0:
|
|
345
|
+
raise ValueError("at least one admin email must be provided to create an account")
|
|
346
|
+
|
|
347
|
+
payload = {
|
|
348
|
+
"name": name,
|
|
349
|
+
"admins": admins,
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
response = client.request(
|
|
353
|
+
method="POST",
|
|
354
|
+
endpoint="v1/organization",
|
|
355
|
+
payload=payload,
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
return cls.from_dict({"client": client} | response.json())
|
|
359
|
+
|
|
360
|
+
def delete(self) -> None:
|
|
361
|
+
"""
|
|
362
|
+
Delete the account.
|
|
363
|
+
|
|
364
|
+
Permanently removes the account (organization) from Nextmv Cloud. You
|
|
365
|
+
must have the administrator role on that account in order to delete it.
|
|
366
|
+
|
|
367
|
+
Raises
|
|
368
|
+
------
|
|
369
|
+
requests.HTTPError
|
|
370
|
+
If the response status code is not 2xx.
|
|
371
|
+
|
|
372
|
+
Examples
|
|
373
|
+
--------
|
|
374
|
+
>>> account.delete() # Permanently deletes the account
|
|
375
|
+
"""
|
|
376
|
+
|
|
377
|
+
_ = self.client.request(
|
|
378
|
+
method="DELETE",
|
|
379
|
+
endpoint=self.organization_endpoint,
|
|
380
|
+
)
|
|
182
381
|
|
|
183
382
|
def queue(self) -> Queue:
|
|
184
|
-
"""
|
|
383
|
+
"""
|
|
384
|
+
Get the queue of runs in the account.
|
|
185
385
|
|
|
186
386
|
Retrieves the current list of runs that are pending or being executed
|
|
187
387
|
in the Nextmv account.
|
|
@@ -198,7 +398,9 @@ class Account:
|
|
|
198
398
|
|
|
199
399
|
Examples
|
|
200
400
|
--------
|
|
201
|
-
>>>
|
|
401
|
+
>>> from nextmv.cloud import Client, Account
|
|
402
|
+
>>> client = Client(api_key="your-api-key")
|
|
403
|
+
>>> account = Account.get(client=client, account_id="your-account-id")
|
|
202
404
|
>>> queue = account.queue()
|
|
203
405
|
>>> for run in queue.runs:
|
|
204
406
|
... print(f"Run {run.id}: {run.name} - Status: {run.status_v2}")
|
|
@@ -207,7 +409,49 @@ class Account:
|
|
|
207
409
|
"""
|
|
208
410
|
response = self.client.request(
|
|
209
411
|
method="GET",
|
|
210
|
-
endpoint=self.
|
|
412
|
+
endpoint=self.account_endpoint + "/queue",
|
|
211
413
|
)
|
|
212
414
|
|
|
213
415
|
return Queue.from_dict(response.json())
|
|
416
|
+
|
|
417
|
+
def update(self, name: str) -> "Account":
|
|
418
|
+
"""
|
|
419
|
+
Update the account.
|
|
420
|
+
|
|
421
|
+
Parameters
|
|
422
|
+
----------
|
|
423
|
+
name : str
|
|
424
|
+
Name of the account.
|
|
425
|
+
|
|
426
|
+
Returns
|
|
427
|
+
-------
|
|
428
|
+
Account
|
|
429
|
+
The updated account.
|
|
430
|
+
|
|
431
|
+
Raises
|
|
432
|
+
------
|
|
433
|
+
requests.HTTPError
|
|
434
|
+
If the response status code is not 2xx.
|
|
435
|
+
|
|
436
|
+
Examples
|
|
437
|
+
--------
|
|
438
|
+
>>> from nextmv.cloud import Client, Account
|
|
439
|
+
>>> client = Client(api_key="your-api-key")
|
|
440
|
+
>>> account = Account.get(client=client, account_id="bunny-logistics")
|
|
441
|
+
>>> updated_account = account.update(name="Bunny Express Logistics")
|
|
442
|
+
>>> print(updated_account.name)
|
|
443
|
+
Bunny Express Logistics
|
|
444
|
+
"""
|
|
445
|
+
|
|
446
|
+
account = self.get(client=self.client, account_id=self.account_id)
|
|
447
|
+
account_dict = account.to_dict()
|
|
448
|
+
payload = account_dict.copy()
|
|
449
|
+
payload["name"] = name
|
|
450
|
+
|
|
451
|
+
response = self.client.request(
|
|
452
|
+
method="PUT",
|
|
453
|
+
endpoint=self.organization_endpoint,
|
|
454
|
+
payload=payload,
|
|
455
|
+
)
|
|
456
|
+
|
|
457
|
+
return Account.from_dict({"client": self.client} | response.json())
|