nextmv 0.10.3.dev0__py3-none-any.whl → 0.35.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.
Files changed (61) hide show
  1. nextmv/__about__.py +1 -1
  2. nextmv/__entrypoint__.py +39 -0
  3. nextmv/__init__.py +57 -0
  4. nextmv/_serialization.py +96 -0
  5. nextmv/base_model.py +79 -9
  6. nextmv/cloud/__init__.py +71 -10
  7. nextmv/cloud/acceptance_test.py +888 -17
  8. nextmv/cloud/account.py +154 -10
  9. nextmv/cloud/application.py +3644 -437
  10. nextmv/cloud/batch_experiment.py +292 -33
  11. nextmv/cloud/client.py +354 -53
  12. nextmv/cloud/ensemble.py +247 -0
  13. nextmv/cloud/input_set.py +121 -4
  14. nextmv/cloud/instance.py +125 -0
  15. nextmv/cloud/package.py +474 -0
  16. nextmv/cloud/scenario.py +410 -0
  17. nextmv/cloud/secrets.py +234 -0
  18. nextmv/cloud/url.py +73 -0
  19. nextmv/cloud/version.py +174 -0
  20. nextmv/default_app/.gitignore +1 -0
  21. nextmv/default_app/README.md +32 -0
  22. nextmv/default_app/app.yaml +12 -0
  23. nextmv/default_app/input.json +5 -0
  24. nextmv/default_app/main.py +37 -0
  25. nextmv/default_app/requirements.txt +2 -0
  26. nextmv/default_app/src/__init__.py +0 -0
  27. nextmv/default_app/src/main.py +37 -0
  28. nextmv/default_app/src/visuals.py +36 -0
  29. nextmv/deprecated.py +47 -0
  30. nextmv/input.py +883 -78
  31. nextmv/local/__init__.py +5 -0
  32. nextmv/local/application.py +1263 -0
  33. nextmv/local/executor.py +1040 -0
  34. nextmv/local/geojson_handler.py +323 -0
  35. nextmv/local/local.py +97 -0
  36. nextmv/local/plotly_handler.py +61 -0
  37. nextmv/local/runner.py +274 -0
  38. nextmv/logger.py +80 -9
  39. nextmv/manifest.py +1472 -0
  40. nextmv/model.py +431 -0
  41. nextmv/options.py +968 -78
  42. nextmv/output.py +1363 -231
  43. nextmv/polling.py +287 -0
  44. nextmv/run.py +1623 -0
  45. nextmv/safe.py +145 -0
  46. nextmv/status.py +122 -0
  47. {nextmv-0.10.3.dev0.dist-info → nextmv-0.35.0.dist-info}/METADATA +51 -288
  48. nextmv-0.35.0.dist-info/RECORD +50 -0
  49. {nextmv-0.10.3.dev0.dist-info → nextmv-0.35.0.dist-info}/WHEEL +1 -1
  50. nextmv/cloud/status.py +0 -29
  51. nextmv/nextroute/__init__.py +0 -2
  52. nextmv/nextroute/check/__init__.py +0 -26
  53. nextmv/nextroute/check/schema.py +0 -141
  54. nextmv/nextroute/schema/__init__.py +0 -19
  55. nextmv/nextroute/schema/input.py +0 -52
  56. nextmv/nextroute/schema/location.py +0 -13
  57. nextmv/nextroute/schema/output.py +0 -136
  58. nextmv/nextroute/schema/stop.py +0 -61
  59. nextmv/nextroute/schema/vehicle.py +0 -68
  60. nextmv-0.10.3.dev0.dist-info/RECORD +0 -28
  61. {nextmv-0.10.3.dev0.dist-info → nextmv-0.35.0.dist-info}/licenses/LICENSE +0 -0
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."""
@@ -0,0 +1,174 @@
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
+ """
18
+
19
+ from datetime import datetime
20
+
21
+ from nextmv.base_model import BaseModel
22
+
23
+
24
+ class VersionExecutableRequirements(BaseModel):
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
+ """
53
+
54
+ executable_type: str
55
+ """Type of the executable."""
56
+ runtime: str
57
+ """Runtime for the executable."""
58
+
59
+
60
+ class VersionExecutable(BaseModel):
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
+ """
97
+
98
+ id: str
99
+ """ID of the version."""
100
+ user_email: str
101
+ """Email of the user who uploaded the executable."""
102
+ uploaded_at: datetime
103
+ """Time the executable was uploaded."""
104
+ requirements: VersionExecutableRequirements
105
+ """Requirements for the executable."""
106
+
107
+
108
+ class Version(BaseModel):
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
+ """
160
+
161
+ id: str
162
+ """ID of the version."""
163
+ application_id: str
164
+ """ID of the application that this is a version of."""
165
+ name: str
166
+ """Name of the version."""
167
+ description: str
168
+ """Description of the version."""
169
+ executable: VersionExecutable
170
+ """Executable for the version."""
171
+ created_at: datetime
172
+ """Creation time of the version."""
173
+ updated_at: datetime
174
+ """Last update time 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
+ pip3 install -r requirements.txt
26
+ ```
27
+
28
+ 2. Run the app.
29
+
30
+ ```bash
31
+ cat input.json | python3 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,5 @@
1
+ {
2
+ "name": "Patches",
3
+ "radius": 6378,
4
+ "distance": 147.6
5
+ }
@@ -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)
@@ -0,0 +1,2 @@
1
+ nextmv>=0.29.3
2
+ plotly>=6.2.0
File without changes
@@ -0,0 +1,37 @@
1
+ from 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)
@@ -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)