nextmv 0.18.0__py3-none-any.whl → 1.0.0.dev2__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 +8 -13
- nextmv/__init__.py +53 -0
- nextmv/_serialization.py +96 -0
- nextmv/base_model.py +54 -9
- nextmv/cli/CONTRIBUTING.md +511 -0
- nextmv/cli/__init__.py +0 -0
- nextmv/cli/cloud/__init__.py +47 -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 +170 -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/shadow/__init__.py +33 -0
- nextmv/cli/cloud/shadow/create.py +184 -0
- nextmv/cli/cloud/shadow/delete.py +68 -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 +43 -0
- nextmv/cli/cloud/shadow/update.py +95 -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 +270 -0
- nextmv/cli/community/list.py +265 -0
- nextmv/cli/configuration/__init__.py +23 -0
- nextmv/cli/configuration/config.py +195 -0
- nextmv/cli/configuration/create.py +94 -0
- nextmv/cli/configuration/delete.py +67 -0
- nextmv/cli/configuration/list.py +77 -0
- nextmv/cli/main.py +188 -0
- nextmv/cli/message.py +153 -0
- nextmv/cli/options.py +206 -0
- nextmv/cli/version.py +38 -0
- nextmv/cloud/__init__.py +71 -17
- nextmv/cloud/acceptance_test.py +757 -51
- nextmv/cloud/account.py +406 -17
- nextmv/cloud/application/__init__.py +957 -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/_shadow.py +314 -0
- nextmv/cloud/application/_utils.py +54 -0
- nextmv/cloud/application/_version.py +303 -0
- nextmv/cloud/assets.py +48 -0
- nextmv/cloud/batch_experiment.py +294 -33
- nextmv/cloud/client.py +307 -66
- nextmv/cloud/ensemble.py +247 -0
- nextmv/cloud/input_set.py +120 -2
- nextmv/cloud/instance.py +133 -8
- nextmv/cloud/integration.py +533 -0
- nextmv/cloud/package.py +168 -53
- nextmv/cloud/scenario.py +410 -0
- nextmv/cloud/secrets.py +234 -0
- nextmv/cloud/shadow.py +190 -0
- nextmv/cloud/url.py +73 -0
- nextmv/cloud/version.py +132 -4
- nextmv/default_app/.gitignore +1 -0
- nextmv/default_app/README.md +32 -0
- nextmv/default_app/app.yaml +12 -0
- nextmv/default_app/input.json +5 -0
- nextmv/default_app/main.py +37 -0
- nextmv/default_app/requirements.txt +2 -0
- nextmv/default_app/src/__init__.py +0 -0
- nextmv/default_app/src/visuals.py +36 -0
- nextmv/deprecated.py +47 -0
- nextmv/input.py +861 -90
- nextmv/local/__init__.py +5 -0
- nextmv/local/application.py +1251 -0
- nextmv/local/executor.py +1042 -0
- nextmv/local/geojson_handler.py +323 -0
- nextmv/local/local.py +97 -0
- nextmv/local/plotly_handler.py +61 -0
- nextmv/local/runner.py +274 -0
- nextmv/logger.py +80 -9
- nextmv/manifest.py +1466 -0
- nextmv/model.py +241 -66
- nextmv/options.py +708 -115
- nextmv/output.py +1301 -274
- nextmv/polling.py +325 -0
- nextmv/run.py +1702 -0
- nextmv/safe.py +145 -0
- nextmv/status.py +122 -0
- nextmv-1.0.0.dev2.dist-info/METADATA +311 -0
- nextmv-1.0.0.dev2.dist-info/RECORD +170 -0
- {nextmv-0.18.0.dist-info → nextmv-1.0.0.dev2.dist-info}/WHEEL +1 -1
- nextmv-1.0.0.dev2.dist-info/entry_points.txt +2 -0
- nextmv/cloud/application.py +0 -1405
- nextmv/cloud/manifest.py +0 -234
- nextmv/cloud/status.py +0 -29
- nextmv-0.18.0.dist-info/METADATA +0 -770
- nextmv-0.18.0.dist-info/RECORD +0 -25
- {nextmv-0.18.0.dist-info → nextmv-1.0.0.dev2.dist-info}/licenses/LICENSE +0 -0
nextmv/cloud/shadow.py
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Classes for working with Nextmv Cloud shadow tests.
|
|
3
|
+
|
|
4
|
+
This module provides classes for interacting with shadow tests in Nextmv Cloud.
|
|
5
|
+
It details the core data structures for these types of experiments.
|
|
6
|
+
|
|
7
|
+
Classes
|
|
8
|
+
-------
|
|
9
|
+
TestComparison
|
|
10
|
+
A structure to define comparison parameters for tests.
|
|
11
|
+
StartEvents
|
|
12
|
+
A structure to define start events for tests.
|
|
13
|
+
TerminationEvents
|
|
14
|
+
A structure to define termination events for tests.
|
|
15
|
+
ShadowTestMetadata
|
|
16
|
+
Metadata for a Nextmv Cloud shadow test.
|
|
17
|
+
ShadowTest
|
|
18
|
+
A Nextmv Cloud shadow test definition.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from datetime import datetime
|
|
22
|
+
from typing import Any
|
|
23
|
+
|
|
24
|
+
from pydantic import AliasChoices, Field
|
|
25
|
+
|
|
26
|
+
from nextmv.base_model import BaseModel
|
|
27
|
+
from nextmv.cloud.batch_experiment import ExperimentStatus
|
|
28
|
+
from nextmv.run import Run
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class TestComparison(BaseModel):
|
|
32
|
+
"""
|
|
33
|
+
A structure to define comparison parameters for tests.
|
|
34
|
+
|
|
35
|
+
You can import the `TestComparison` class directly from `cloud`:
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from nextmv.cloud import TestComparison
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Parameters
|
|
42
|
+
----------
|
|
43
|
+
baseline_instance_id : str
|
|
44
|
+
ID of the baseline instance for comparison.
|
|
45
|
+
candidate_instance_ids : list[str]
|
|
46
|
+
List of candidate instance IDs to compare against the baseline.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
baseline_instance_id: str
|
|
50
|
+
"""ID of the baseline instance for comparison."""
|
|
51
|
+
candidate_instance_ids: list[str]
|
|
52
|
+
"""List of candidate instance IDs to compare against the baseline."""
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class StartEvents(BaseModel):
|
|
56
|
+
"""
|
|
57
|
+
A structure to define start events for tests.
|
|
58
|
+
|
|
59
|
+
You can import the `StartEvents` class directly from `cloud`:
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
from nextmv.cloud import StartEvents
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Parameters
|
|
66
|
+
----------
|
|
67
|
+
time : datetime, optional
|
|
68
|
+
Scheduled time for the test to start.
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
time: datetime | None = None
|
|
72
|
+
"""Scheduled time for the test to start."""
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class TerminationEvents(BaseModel):
|
|
76
|
+
"""
|
|
77
|
+
A structure to define termination events for tests.
|
|
78
|
+
|
|
79
|
+
You can import the `TerminationEvents` class directly from `cloud`:
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
from nextmv.cloud import TerminationEvents
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Parameters
|
|
86
|
+
----------
|
|
87
|
+
time : datetime, optional
|
|
88
|
+
Scheduled time for the test to terminate.
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
maximum_runs: int
|
|
92
|
+
"""
|
|
93
|
+
Maximum number of runs for the test. Min should be 1, max should be 300.
|
|
94
|
+
"""
|
|
95
|
+
time: datetime | None = None
|
|
96
|
+
"""
|
|
97
|
+
Scheduled time for the test to terminate. A zero value means no
|
|
98
|
+
limit.
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
def model_post_init(self, __context):
|
|
102
|
+
if self.maximum_runs < 1:
|
|
103
|
+
raise ValueError("maximum_runs must be at least 1")
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class ShadowTestMetadata(BaseModel):
|
|
107
|
+
"""
|
|
108
|
+
Metadata for a Nextmv Cloud shadow test.
|
|
109
|
+
|
|
110
|
+
You can import the `ShadowTestMetadata` class directly from `cloud`:
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
from nextmv.cloud import ShadowTestMetadata
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Parameters
|
|
117
|
+
----------
|
|
118
|
+
shadow_test_id : str, optional
|
|
119
|
+
The unique identifier of the shadow test.
|
|
120
|
+
name : str, optional
|
|
121
|
+
Name of the shadow test.
|
|
122
|
+
description : str, optional
|
|
123
|
+
Description of the shadow test.
|
|
124
|
+
app_id : str, optional
|
|
125
|
+
ID of the application to which the shadow test belongs.
|
|
126
|
+
created_at : datetime, optional
|
|
127
|
+
Creation date of the shadow test.
|
|
128
|
+
updated_at : datetime, optional
|
|
129
|
+
Last update date of the shadow test.
|
|
130
|
+
status : ExperimentStatus, optional
|
|
131
|
+
The current status of the shadow test.
|
|
132
|
+
"""
|
|
133
|
+
|
|
134
|
+
shadow_test_id: str | None = Field(
|
|
135
|
+
serialization_alias="id",
|
|
136
|
+
validation_alias=AliasChoices("id", "shadow_test_id"),
|
|
137
|
+
default=None,
|
|
138
|
+
)
|
|
139
|
+
"""The unique identifier of the shadow test."""
|
|
140
|
+
name: str | None = None
|
|
141
|
+
"""Name of the shadow test."""
|
|
142
|
+
description: str | None = None
|
|
143
|
+
"""Description of the shadow test."""
|
|
144
|
+
app_id: str | None = None
|
|
145
|
+
"""ID of the application to which the shadow test belongs."""
|
|
146
|
+
created_at: datetime | None = None
|
|
147
|
+
"""Creation date of the shadow test."""
|
|
148
|
+
updated_at: datetime | None = None
|
|
149
|
+
"""Last update date of the shadow test."""
|
|
150
|
+
status: ExperimentStatus | None = None
|
|
151
|
+
"""The current status of the shadow test."""
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class ShadowTest(ShadowTestMetadata):
|
|
155
|
+
"""
|
|
156
|
+
A Nextmv Cloud shadow test definition.
|
|
157
|
+
|
|
158
|
+
A shadow test is a type of experiment where runs are executed in parallel
|
|
159
|
+
to compare different instances.
|
|
160
|
+
|
|
161
|
+
You can import the `ShadowTest` class directly from `cloud`:
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from nextmv.cloud import ShadowTest
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Parameters
|
|
168
|
+
----------
|
|
169
|
+
completed_at : datetime, optional
|
|
170
|
+
Completion date of the shadow test, if applicable.
|
|
171
|
+
comparisons : list[TestComparison], optional
|
|
172
|
+
List of test comparisons defined in the shadow test.
|
|
173
|
+
start_events : StartEvents, optional
|
|
174
|
+
Start events for the shadow test.
|
|
175
|
+
termination_events : TerminationEvents, optional
|
|
176
|
+
Termination events for the shadow test.
|
|
177
|
+
"""
|
|
178
|
+
|
|
179
|
+
completed_at: datetime | None = None
|
|
180
|
+
"""Completion date of the shadow test, if applicable."""
|
|
181
|
+
comparisons: list[TestComparison] | None = None
|
|
182
|
+
"""List of test comparisons defined in the shadow test."""
|
|
183
|
+
start_events: StartEvents | None = None
|
|
184
|
+
"""Start events for the shadow test."""
|
|
185
|
+
termination_events: TerminationEvents | None = None
|
|
186
|
+
"""Termination events for the shadow test."""
|
|
187
|
+
grouped_distributional_summaries: list[dict[str, Any]] | None = None
|
|
188
|
+
"""Grouped distributional summaries of the shadow test."""
|
|
189
|
+
runs: list[Run] | None = None
|
|
190
|
+
"""List of runs in the shadow test."""
|
nextmv/cloud/url.py
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module for declarations related to upload and download URLs in Nextmv Cloud.
|
|
3
|
+
|
|
4
|
+
Classes
|
|
5
|
+
-------
|
|
6
|
+
DownloadURL
|
|
7
|
+
Represents a download URL for fetching content from Nextmv Cloud.
|
|
8
|
+
UploadURL
|
|
9
|
+
Represents an upload URL for sending content to Nextmv Cloud.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from nextmv.base_model import BaseModel
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class DownloadURL(BaseModel):
|
|
16
|
+
"""
|
|
17
|
+
Result of getting a download URL.
|
|
18
|
+
|
|
19
|
+
You can import the `DownloadURL` class directly from `cloud`:
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from nextmv.cloud import DownloadURL
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
This class represents a download URL that can be used to fetch content
|
|
26
|
+
from Nextmv Cloud, typically used for downloading large run results.
|
|
27
|
+
|
|
28
|
+
Attributes
|
|
29
|
+
----------
|
|
30
|
+
url : str
|
|
31
|
+
URL to use for downloading the file.
|
|
32
|
+
|
|
33
|
+
Examples
|
|
34
|
+
--------
|
|
35
|
+
>>> download_url = DownloadURL(url="https://example.com/download")
|
|
36
|
+
>>> response = requests.get(download_url.url)
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
url: str
|
|
40
|
+
"""URL to use for downloading the file."""
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class UploadURL(BaseModel):
|
|
44
|
+
"""
|
|
45
|
+
Result of getting an upload URL.
|
|
46
|
+
|
|
47
|
+
You can import the `UploadURL` class directly from `cloud`:
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from nextmv.cloud import UploadURL
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
This class represents an upload URL that can be used to send data to
|
|
54
|
+
Nextmv Cloud, typically used for uploading large inputs for runs.
|
|
55
|
+
|
|
56
|
+
Attributes
|
|
57
|
+
----------
|
|
58
|
+
upload_id : str
|
|
59
|
+
ID of the upload, used to reference the uploaded content.
|
|
60
|
+
upload_url : str
|
|
61
|
+
URL to use for uploading the file.
|
|
62
|
+
|
|
63
|
+
Examples
|
|
64
|
+
--------
|
|
65
|
+
>>> upload_url = UploadURL(upload_id="123", upload_url="https://example.com/upload")
|
|
66
|
+
>>> with open("large_input.json", "rb") as f:
|
|
67
|
+
... requests.put(upload_url.upload_url, data=f)
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
upload_id: str
|
|
71
|
+
"""ID of the upload."""
|
|
72
|
+
upload_url: str
|
|
73
|
+
"""URL to use for uploading the file."""
|
nextmv/cloud/version.py
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Manages application versions within the Nextmv Cloud API.
|
|
2
|
+
|
|
3
|
+
This module provides data models for representing application versions,
|
|
4
|
+
their executables, and associated requirements. These models are used
|
|
5
|
+
for interacting with version-related endpoints of the Nextmv Cloud API,
|
|
6
|
+
allowing users to define, retrieve, and manage different versions of their
|
|
7
|
+
decision applications.
|
|
8
|
+
|
|
9
|
+
Classes
|
|
10
|
+
-------
|
|
11
|
+
VersionExecutableRequirements
|
|
12
|
+
Defines the requirements for a version's executable, such as type and runtime.
|
|
13
|
+
VersionExecutable
|
|
14
|
+
Represents the executable artifact for a specific application version.
|
|
15
|
+
Version
|
|
16
|
+
Represents a version of an application, linking to its executable and metadata.
|
|
17
|
+
"""
|
|
2
18
|
|
|
3
19
|
from datetime import datetime
|
|
4
20
|
|
|
@@ -6,7 +22,34 @@ from nextmv.base_model import BaseModel
|
|
|
6
22
|
|
|
7
23
|
|
|
8
24
|
class VersionExecutableRequirements(BaseModel):
|
|
9
|
-
"""
|
|
25
|
+
"""
|
|
26
|
+
Requirements for a version executable.
|
|
27
|
+
|
|
28
|
+
You can import the `VersionExecutableRequirements` class directly from `cloud`:
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
from nextmv.cloud import VersionExecutableRequirements
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
These requirements specify the environment and type of executable needed
|
|
35
|
+
to run a particular version of an application.
|
|
36
|
+
|
|
37
|
+
Parameters
|
|
38
|
+
----------
|
|
39
|
+
executable_type : str
|
|
40
|
+
The type of the executable (e.g., "binary", "docker").
|
|
41
|
+
runtime : str
|
|
42
|
+
The runtime environment for the executable (e.g., "go", "python").
|
|
43
|
+
|
|
44
|
+
Examples
|
|
45
|
+
--------
|
|
46
|
+
>>> requirements = VersionExecutableRequirements(
|
|
47
|
+
... executable_type="binary",
|
|
48
|
+
... runtime="go1.x"
|
|
49
|
+
... )
|
|
50
|
+
>>> print(requirements.executable_type)
|
|
51
|
+
binary
|
|
52
|
+
"""
|
|
10
53
|
|
|
11
54
|
executable_type: str
|
|
12
55
|
"""Type of the executable."""
|
|
@@ -15,7 +58,42 @@ class VersionExecutableRequirements(BaseModel):
|
|
|
15
58
|
|
|
16
59
|
|
|
17
60
|
class VersionExecutable(BaseModel):
|
|
18
|
-
"""
|
|
61
|
+
"""
|
|
62
|
+
Executable for a version.
|
|
63
|
+
|
|
64
|
+
You can import the `VersionExecutable` class directly from `cloud`:
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
from nextmv.cloud import VersionExecutable
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
This class holds information about the actual executable file or image
|
|
71
|
+
associated with an application version, including who uploaded it and when.
|
|
72
|
+
|
|
73
|
+
Parameters
|
|
74
|
+
----------
|
|
75
|
+
id : str
|
|
76
|
+
Unique identifier for the version executable.
|
|
77
|
+
user_email : str
|
|
78
|
+
Email of the user who uploaded the executable.
|
|
79
|
+
uploaded_at : datetime
|
|
80
|
+
Timestamp indicating when the executable was uploaded.
|
|
81
|
+
requirements : VersionExecutableRequirements
|
|
82
|
+
The specific requirements for this executable.
|
|
83
|
+
|
|
84
|
+
Examples
|
|
85
|
+
--------
|
|
86
|
+
>>> from datetime import datetime
|
|
87
|
+
>>> reqs = VersionExecutableRequirements(executable_type="docker", runtime="custom")
|
|
88
|
+
>>> executable = VersionExecutable(
|
|
89
|
+
... id="exec-123",
|
|
90
|
+
... user_email="user@example.com",
|
|
91
|
+
... uploaded_at=datetime.now(),
|
|
92
|
+
... requirements=reqs
|
|
93
|
+
... )
|
|
94
|
+
>>> print(executable.id)
|
|
95
|
+
exec-123
|
|
96
|
+
"""
|
|
19
97
|
|
|
20
98
|
id: str
|
|
21
99
|
"""ID of the version."""
|
|
@@ -28,7 +106,57 @@ class VersionExecutable(BaseModel):
|
|
|
28
106
|
|
|
29
107
|
|
|
30
108
|
class Version(BaseModel):
|
|
31
|
-
"""
|
|
109
|
+
"""
|
|
110
|
+
A version of an application representing a code artifact or a compiled binary.
|
|
111
|
+
|
|
112
|
+
You can import the `Version` class directly from `cloud`:
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
from nextmv.cloud import Version
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
This class encapsulates all details of a specific version of an application,
|
|
119
|
+
including its metadata, associated executable, and timestamps.
|
|
120
|
+
|
|
121
|
+
Parameters
|
|
122
|
+
----------
|
|
123
|
+
id : str
|
|
124
|
+
Unique identifier for the version.
|
|
125
|
+
application_id : str
|
|
126
|
+
Identifier of the application to which this version belongs.
|
|
127
|
+
name : str
|
|
128
|
+
User-defined name for the version (e.g., "v1.0.0", "feature-branch-build").
|
|
129
|
+
description : str
|
|
130
|
+
A more detailed description of the version and its changes.
|
|
131
|
+
executable : VersionExecutable
|
|
132
|
+
The executable artifact associated with this version.
|
|
133
|
+
created_at : datetime
|
|
134
|
+
Timestamp indicating when the version was created.
|
|
135
|
+
updated_at : datetime
|
|
136
|
+
Timestamp indicating when the version was last updated.
|
|
137
|
+
|
|
138
|
+
Examples
|
|
139
|
+
--------
|
|
140
|
+
>>> from datetime import datetime
|
|
141
|
+
>>> reqs = VersionExecutableRequirements(executable_type="binary", runtime="java11")
|
|
142
|
+
>>> exe = VersionExecutable(
|
|
143
|
+
... id="exec-abc",
|
|
144
|
+
... user_email="dev@example.com",
|
|
145
|
+
... uploaded_at=datetime.now(),
|
|
146
|
+
... requirements=reqs
|
|
147
|
+
... )
|
|
148
|
+
>>> version_info = Version(
|
|
149
|
+
... id="ver-xyz",
|
|
150
|
+
... application_id="app-123",
|
|
151
|
+
... name="Initial Release",
|
|
152
|
+
... description="First stable release of the model.",
|
|
153
|
+
... executable=exe,
|
|
154
|
+
... created_at=datetime.now(),
|
|
155
|
+
... updated_at=datetime.now()
|
|
156
|
+
... )
|
|
157
|
+
>>> print(version_info.name)
|
|
158
|
+
Initial Release
|
|
159
|
+
"""
|
|
32
160
|
|
|
33
161
|
id: str
|
|
34
162
|
"""ID of the version."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.nextmv
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Nextmv application
|
|
2
|
+
|
|
3
|
+
This is the basic structure of a Nextmv application.
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
├── app.yaml
|
|
7
|
+
├── main.py
|
|
8
|
+
├── README.md
|
|
9
|
+
├── requirements.txt
|
|
10
|
+
└── src
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
* `app.yaml`: App manifest, containing the configuration to run the app
|
|
14
|
+
remotely on Nextmv Cloud.
|
|
15
|
+
* `main.py`: Entry point for the app.
|
|
16
|
+
* `README.md`: Description of the app.
|
|
17
|
+
* `requirements.txt`: Python dependencies for the app.
|
|
18
|
+
* `src/`: Source code for the app.
|
|
19
|
+
|
|
20
|
+
A sample input file is also provided as `input.json`.
|
|
21
|
+
|
|
22
|
+
1. Install packages.
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install -r requirements.txt
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
2. Run the app.
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
cat input.json | python main.py
|
|
32
|
+
```
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# This manifest holds the information the app needs to run on the Nextmv Cloud.
|
|
2
|
+
type: python
|
|
3
|
+
runtime: ghcr.io/nextmv-io/runtime/python:3.11
|
|
4
|
+
python:
|
|
5
|
+
# All listed packages will get bundled with the app.
|
|
6
|
+
pip-requirements: requirements.txt
|
|
7
|
+
|
|
8
|
+
# List all files/directories that should be included in the app. Globbing
|
|
9
|
+
# (e.g.: configs/*.json) is supported.
|
|
10
|
+
files:
|
|
11
|
+
- src/
|
|
12
|
+
- main.py
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from src.visuals import create_visuals
|
|
2
|
+
|
|
3
|
+
import nextmv
|
|
4
|
+
|
|
5
|
+
# Read the input from stdin.
|
|
6
|
+
input = nextmv.load()
|
|
7
|
+
name = input.data["name"]
|
|
8
|
+
|
|
9
|
+
options = nextmv.Options(
|
|
10
|
+
nextmv.Option("details", bool, True, "Print details to logs. Default true.", False),
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
##### Insert model here
|
|
14
|
+
|
|
15
|
+
# Print logs that render in the run view in Nextmv Console.
|
|
16
|
+
message = f"Hello, {name}"
|
|
17
|
+
nextmv.log(message)
|
|
18
|
+
|
|
19
|
+
if options.details:
|
|
20
|
+
detail = f"You are {input.data['distance']} million km from the sun"
|
|
21
|
+
nextmv.log(detail)
|
|
22
|
+
|
|
23
|
+
assets = create_visuals(name, input.data["radius"], input.data["distance"])
|
|
24
|
+
|
|
25
|
+
# Write output and statistics.
|
|
26
|
+
output = nextmv.Output(
|
|
27
|
+
options=options,
|
|
28
|
+
solution={"message": message},
|
|
29
|
+
statistics=nextmv.Statistics(
|
|
30
|
+
result=nextmv.ResultStatistics(
|
|
31
|
+
value=1.23,
|
|
32
|
+
custom={"message": message},
|
|
33
|
+
),
|
|
34
|
+
),
|
|
35
|
+
assets=assets,
|
|
36
|
+
)
|
|
37
|
+
nextmv.write(output)
|
|
File without changes
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
import plotly.graph_objects as go
|
|
4
|
+
|
|
5
|
+
import nextmv
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def create_visuals(name: str, radius: float, distance: float) -> list[nextmv.Asset]:
|
|
9
|
+
"""Create a Plotly bar chart with radius and distance for a planet."""
|
|
10
|
+
|
|
11
|
+
fig = go.Figure()
|
|
12
|
+
fig.add_trace(
|
|
13
|
+
go.Bar(x=[name], y=[radius], name="Radius (km)", marker_color="red", opacity=0.5),
|
|
14
|
+
)
|
|
15
|
+
fig.add_trace(
|
|
16
|
+
go.Bar(x=[name], y=[distance], name="Distance (Millions km)", marker_color="blue", opacity=0.5),
|
|
17
|
+
)
|
|
18
|
+
fig.update_layout(
|
|
19
|
+
title="Radius and Distance by Planet", xaxis_title="Planet", yaxis_title="Values", barmode="group"
|
|
20
|
+
)
|
|
21
|
+
fig = fig.to_json()
|
|
22
|
+
|
|
23
|
+
assets = [
|
|
24
|
+
nextmv.Asset(
|
|
25
|
+
name="Plotly example",
|
|
26
|
+
content_type="json",
|
|
27
|
+
visual=nextmv.Visual(
|
|
28
|
+
visual_schema=nextmv.VisualSchema.PLOTLY,
|
|
29
|
+
visual_type="custom-tab",
|
|
30
|
+
label="Charts",
|
|
31
|
+
),
|
|
32
|
+
content=[json.loads(fig)],
|
|
33
|
+
)
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
return assets
|
nextmv/deprecated.py
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Utilities for handling deprecated functionality within the Nextmv Python SDK.
|
|
2
|
+
|
|
3
|
+
This module provides tools to mark functions, methods, or features as deprecated,
|
|
4
|
+
emitting appropriate warnings to users. These warnings inform users that the
|
|
5
|
+
functionality will be removed in a future release and suggest alternative approaches.
|
|
6
|
+
|
|
7
|
+
The main purpose of this module is to help with the smooth transition when
|
|
8
|
+
API changes are necessary, giving users time to update their code before
|
|
9
|
+
functionality is removed completely.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import warnings
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def deprecated(name: str, reason: str) -> None:
|
|
16
|
+
"""Mark functionality as deprecated with a warning message.
|
|
17
|
+
|
|
18
|
+
This function emits a DeprecationWarning when called, indicating that
|
|
19
|
+
the functionality will be removed in a future release.
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
name : str
|
|
24
|
+
The name of the function, method, or feature being deprecated.
|
|
25
|
+
reason : str
|
|
26
|
+
The reason why the functionality is being deprecated, possibly
|
|
27
|
+
with suggestions for alternative approaches.
|
|
28
|
+
|
|
29
|
+
Notes
|
|
30
|
+
-----
|
|
31
|
+
This function temporarily changes the warning filter to ensure the
|
|
32
|
+
deprecation warning is shown, then resets it afterward.
|
|
33
|
+
|
|
34
|
+
Examples
|
|
35
|
+
--------
|
|
36
|
+
>>> def some_function():
|
|
37
|
+
... deprecated("feature_x", "Use feature_y instead")
|
|
38
|
+
... # function implementation
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
warnings.simplefilter("always", DeprecationWarning)
|
|
42
|
+
warnings.warn(
|
|
43
|
+
f"{name}: {reason}. This functionality will be removed in a future release",
|
|
44
|
+
category=DeprecationWarning,
|
|
45
|
+
stacklevel=2,
|
|
46
|
+
)
|
|
47
|
+
warnings.simplefilter("default", DeprecationWarning)
|