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/safe.py ADDED
@@ -0,0 +1,145 @@
1
+ """
2
+
3
+ The safe module contains utilities for generating “safe” IDs and human-readable
4
+ names.
5
+
6
+ Functions
7
+ ---------
8
+ safe_name_and_id
9
+ Generate a safe ID and human-readable name from a prefix and user-supplied
10
+ identifier.
11
+ safe_id
12
+ Generate a safe ID from a prefix.
13
+ """
14
+
15
+ import re
16
+ import secrets
17
+ import string
18
+
19
+ ENTITY_ID_CHAR_COUNT_MAX: int = 40
20
+ INDEX_TAG_CHAR_COUNT: int = 3 # room reserved for “-001”, “-xyz”, etc.
21
+ RE_NON_ALNUM = re.compile(r"[^A-Za-z0-9]+")
22
+
23
+
24
+ def _kebab_case(value: str) -> str:
25
+ """Convert arbitrary text to `kebab-case` (lower-case, hyphen-separated)."""
26
+
27
+ cleaned = RE_NON_ALNUM.sub(" ", value).strip()
28
+ return "-".join(word.lower() for word in cleaned.split())
29
+
30
+
31
+ def _start_case(value: str) -> str:
32
+ """Convert `kebab-case` (or any hyphen/underscore string) to `Start Case`."""
33
+
34
+ cleaned = re.sub(r"[-_]+", " ", value)
35
+ return " ".join(word.capitalize() for word in cleaned.split())
36
+
37
+
38
+ def _nanoid(size: int = 8, alphabet: str = string.ascii_lowercase + string.digits) -> str:
39
+ """Simple nanoid clone using the std-lib `secrets` module."""
40
+
41
+ return "".join(secrets.choice(alphabet) for _ in range(size))
42
+
43
+
44
+ def safe_name_and_id(prefix: str, entity_id: str) -> tuple[str, str]:
45
+ """
46
+ Generate a safe ID and human-readable name from a prefix and user-supplied
47
+ identifier.
48
+
49
+ You can import the `safe_name_and_id` function directly from `nextmv`:
50
+
51
+ ```python
52
+ from nextmv import safe_name_and_id
53
+ ```
54
+
55
+ Parameters
56
+ ----------
57
+ prefix : str
58
+ Prefix to use for the ID.
59
+ entity_id : str
60
+ User-supplied identifier. This will be converted to `kebab-case` and
61
+ truncated to fit within the safe ID length.
62
+
63
+ Returns
64
+ -------
65
+ tuple[str, str]
66
+ A tuple containing the human-readable name and the safe ID.
67
+
68
+ Examples
69
+ --------
70
+ >>> safe_name_and_id("app", "My Application 123!")
71
+ ('App My Application 123', 'app-my-application-123-4f5g6h7j')
72
+ """
73
+
74
+ if not prefix or not entity_id:
75
+ return "", ""
76
+
77
+ safe_user_defined_id = _kebab_case(entity_id)
78
+ random_slug = _nanoid(8)
79
+
80
+ # Space available for user text once prefix, random slug and separator "-"
81
+ # are accounted for
82
+ safe_id_max = (
83
+ ENTITY_ID_CHAR_COUNT_MAX
84
+ - INDEX_TAG_CHAR_COUNT
85
+ - len(prefix)
86
+ - (len(random_slug) + 1) # +1 for the hyphen before the slug
87
+ )
88
+
89
+ safe_id_parts: list[str] = [prefix]
90
+
91
+ for word in safe_user_defined_id.split("-"):
92
+ # Trim individual word if it alone would overflow
93
+ safe_slug = word[: safe_id_max - 1] if len(word) > safe_id_max else word
94
+
95
+ # Will the combined ID (so far) overflow if we add this slug?
96
+ prospective_len = len("-".join(safe_id_parts + [safe_slug]))
97
+ if prospective_len >= safe_id_max:
98
+ break
99
+ safe_id_parts.append(safe_slug)
100
+
101
+ safe_id = "-".join(filter(None, safe_id_parts)) + f"-{random_slug}"
102
+ safe_name = _start_case(safe_id)
103
+
104
+ return safe_name, safe_id
105
+
106
+
107
+ def safe_id(prefix: str) -> str:
108
+ """
109
+ Generate a safe ID from a prefix.
110
+
111
+ You can import the `safe_id` function directly from `nextmv`:
112
+
113
+ ```python
114
+ from nextmv import safe_id
115
+ ```
116
+
117
+ Parameters
118
+ ----------
119
+ prefix : str
120
+ Prefix to use for the ID.
121
+
122
+ Returns
123
+ -------
124
+ str
125
+ A safe ID.
126
+
127
+ Examples
128
+ --------
129
+ >>> safe_id("app")
130
+ 'app-4f5g6h7j'
131
+ """
132
+
133
+ random_slug = _nanoid(8)
134
+ # Space available for user text once prefix, random slug and separator "-"
135
+ # are accounted for
136
+ safe_id_max = (
137
+ ENTITY_ID_CHAR_COUNT_MAX - INDEX_TAG_CHAR_COUNT - (len(random_slug) + 1) # +1 for the hyphen before the slug
138
+ )
139
+
140
+ if len(prefix) > safe_id_max:
141
+ return prefix[: safe_id_max - 1] + f"-{random_slug}"
142
+
143
+ safe_id = f"{prefix}-{random_slug}"
144
+
145
+ return safe_id
nextmv/status.py ADDED
@@ -0,0 +1,122 @@
1
+ """
2
+ Provides status enums for Nextmv application runs.
3
+
4
+ This module defines enumerations for representing the status of a run in a
5
+ Nextmv application. It includes a deprecated `Status` enum and the current
6
+ `StatusV2` enum.
7
+
8
+ Classes
9
+ -------
10
+ Status
11
+ Deprecated status of a run.
12
+ StatusV2
13
+ Represents the status of a run.
14
+ """
15
+
16
+ from enum import Enum
17
+
18
+
19
+ class Status(str, Enum):
20
+ """
21
+ !!! warning
22
+ `Status` is deprecated, use `StatusV2` instead.
23
+
24
+ Status of a run.
25
+
26
+ You can import the `Status` class directly from `nextmv`:
27
+
28
+ ```python
29
+ from nextmv import Status
30
+ ```
31
+
32
+ This enum represents the possible states of a run. It is deprecated and
33
+ `StatusV2` should be used for new implementations.
34
+
35
+ Attributes
36
+ ----------
37
+ failed : str
38
+ Run failed.
39
+ running : str
40
+ Run is running.
41
+ succeeded : str
42
+ Run succeeded.
43
+
44
+ Examples
45
+ --------
46
+ >>> from nextmv.cloud import Status
47
+ >>> current_status = Status.running
48
+ >>> if current_status == Status.succeeded:
49
+ ... print("Run completed successfully.")
50
+ ... elif current_status == Status.failed:
51
+ ... print("Run failed.")
52
+ ... else:
53
+ ... print(f"Run is currently {current_status.value}.")
54
+ Run is currently running.
55
+
56
+ """
57
+
58
+ failed = "failed"
59
+ """Run failed."""
60
+ running = "running"
61
+ """Run is running."""
62
+ succeeded = "succeeded"
63
+ """Run succeeded."""
64
+
65
+
66
+ class StatusV2(str, Enum):
67
+ """
68
+ Status of a run.
69
+
70
+ You can import the `StatusV2` class directly from `nextmv`:
71
+
72
+ ```python
73
+ from nextmv import StatusV2
74
+ ```
75
+
76
+ This enum represents the comprehensive set of possible states for a run
77
+ in Nextmv.
78
+
79
+ Attributes
80
+ ----------
81
+ canceled : str
82
+ Run was canceled.
83
+ failed : str
84
+ Run failed.
85
+ none : str
86
+ Run has no status.
87
+ queued : str
88
+ Run is queued.
89
+ running : str
90
+ Run is running.
91
+ succeeded : str
92
+ Run succeeded.
93
+
94
+ Examples
95
+ --------
96
+ >>> from nextmv.cloud import StatusV2
97
+ >>> run_status = StatusV2.queued
98
+ >>> print(f"The run status is: {run_status.value}")
99
+ The run status is: queued
100
+
101
+ >>> if run_status == StatusV2.succeeded:
102
+ ... print("Processing complete.")
103
+ ... elif run_status in [StatusV2.queued, StatusV2.running]:
104
+ ... print("Processing in progress.")
105
+ ... else:
106
+ ... print("Processing has not started or has ended with issues.")
107
+ Processing in progress.
108
+
109
+ """
110
+
111
+ canceled = "canceled"
112
+ """Run was canceled."""
113
+ failed = "failed"
114
+ """Run failed."""
115
+ none = "none"
116
+ """Run has no status."""
117
+ queued = "queued"
118
+ """Run is queued."""
119
+ running = "running"
120
+ """Run is running."""
121
+ succeeded = "succeeded"
122
+ """Run succeeded."""
@@ -1,9 +1,9 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: nextmv
3
- Version: 0.10.3.dev0
4
- Summary: The Python SDK for Nextmv
3
+ Version: 0.35.0
4
+ Summary: The all-purpose Python SDK for Nextmv
5
5
  Project-URL: Homepage, https://www.nextmv.io
6
- Project-URL: Documentation, https://www.nextmv.io/docs
6
+ Project-URL: Documentation, https://nextmv-py.docs.nextmv.io/en/latest/nextmv/
7
7
  Project-URL: Repository, https://github.com/nextmv-io/nextmv-py
8
8
  Author-email: Nextmv <tech@nextmv.io>
9
9
  Maintainer-email: Nextmv <tech@nextmv.io>
@@ -213,309 +213,72 @@ Keywords: decision engineering,decision science,decisions,nextmv,operations rese
213
213
  Classifier: License :: OSI Approved :: Apache Software License
214
214
  Classifier: Operating System :: OS Independent
215
215
  Classifier: Programming Language :: Python :: 3
216
- Requires-Python: >=3.8
216
+ Classifier: Programming Language :: Python :: 3.10
217
+ Classifier: Programming Language :: Python :: 3.11
218
+ Classifier: Programming Language :: Python :: 3.12
219
+ Classifier: Programming Language :: Python :: 3.13
220
+ Requires-Python: >=3.10
217
221
  Requires-Dist: pydantic>=2.5.2
218
222
  Requires-Dist: pyyaml>=6.0.1
219
223
  Requires-Dist: requests>=2.31.0
220
224
  Requires-Dist: urllib3>=2.1.0
225
+ Provides-Extra: all
226
+ Requires-Dist: folium>=0.20.0; extra == 'all'
227
+ Requires-Dist: mlflow>=2.17.2; extra == 'all'
228
+ Requires-Dist: plotly>=6.0.1; extra == 'all'
229
+ Provides-Extra: dev
230
+ Requires-Dist: build>=1.0.3; extra == 'dev'
231
+ Requires-Dist: folium>=0.20.0; extra == 'dev'
232
+ Requires-Dist: mlflow>=2.19.0; extra == 'dev'
233
+ Requires-Dist: nextroute>=1.11.1; extra == 'dev'
234
+ Requires-Dist: openpyxl>=3.1.5; extra == 'dev'
235
+ Requires-Dist: pandas>=2.2.3; extra == 'dev'
236
+ Requires-Dist: plotly>=6.0.1; extra == 'dev'
237
+ Requires-Dist: pydantic>=2.5.2; extra == 'dev'
238
+ Requires-Dist: pyyaml>=6.0.1; extra == 'dev'
239
+ Requires-Dist: requests>=2.31.0; extra == 'dev'
240
+ Requires-Dist: ruff>=0.1.7; extra == 'dev'
241
+ Requires-Dist: twine>=4.0.2; extra == 'dev'
242
+ Requires-Dist: urllib3>=2.1.0; extra == 'dev'
221
243
  Description-Content-Type: text/markdown
222
244
 
223
245
  # Nextmv Python SDK
224
246
 
225
- This is the Python SDK for the Nextmv Platform.
247
+ <!-- markdownlint-disable MD033 MD013 -->
226
248
 
227
- ## Installation
228
-
229
- Requires Python `>=3.8`. Install using `pip`:
230
-
231
- ```bash
232
- pip install nextmv
233
- ```
234
-
235
- ## Usage
236
-
237
- The Nextmv Python SDK is used to interact with various parts of the Nextmv
238
- Platform:
239
-
240
- - [Working with a Decision Model][working-with-a-decision-model]: Get to know
241
- the functionality for running decision models. These API functions work
242
- the same way in any machine (local or hosted).
243
- - [Cloud][cloud]: Interact with the Nextmv Cloud API.
244
-
245
- ### Working with a Decision Model
249
+ <p align="center">
250
+ <a href="https://nextmv.io"><img src="https://cdn.prod.website-files.com/60dee0fad10d14c8ab66dd74/674628a824bc14307c1727aa_blog-prototype-p-2000.png" alt="Nextmv" width="45%"></a>
251
+ </p>
252
+ <p align="center">
253
+ <em>Nextmv: The home for all your optimization work</em>
254
+ </p>
255
+ <p align="center">
256
+ <a href="https://pypi.org/project/nextmv" target="_blank">
257
+ <img src="https://img.shields.io/pypi/pyversions/nextmv.svg?color=%2334D058" alt="Supported Python versions">
258
+ </a>
259
+ <a href="https://pypi.org/project/nextmv" target="_blank">
260
+ <img src="https://img.shields.io/pypi/v/nextmv?color=%2334D058&label=nextmv" alt="Package version">
261
+ </a>
262
+ </p>
246
263
 
247
- To run a model, you can use the various helper functionality provided by the
248
- SDK. Note that when you create an app that runs locally in your machine, it
249
- will run in the same way in a Nextmv Cloud-hosted machine.
264
+ <!-- markdownlint-enable MD033 MD013 -->
250
265
 
251
- #### Options
266
+ Welcome to `nextmv`, the general Python SDK for the Nextmv Platform.
252
267
 
253
- Use options to capture parameters (i.e.: configurations) for the run:
268
+ 📖 To learn more about the `nextmv`, visit the [docs][docs].
254
269
 
255
- ```python
256
- import nextmv
257
-
258
- options = nextmv.Options(
259
- nextmv.Parameter("str_option", str, "default value", "A string option", required=True),
260
- nextmv.Parameter("int_option", int, 1, "An int option", required=False),
261
- nextmv.Parameter("float_option", float, 1.0, "A float option", required=False),
262
- nextmv.Parameter("bool_option", bool, True, "A bool option", required=True),
263
- )
264
-
265
- print(options.str_option)
266
- print(options.int_option)
267
- print(options.float_option)
268
- print(options.bool_option)
269
- print(options.to_dict())
270
- ```
271
-
272
- By using options, you are able to pass in the values of the parameters with CLI
273
- arguments or environment variables.
270
+ ## Installation
274
271
 
275
- <!-- markdownlint-disable -->
272
+ Requires Python `>=3.10`. Install using `pip`:
276
273
 
277
274
  ```bash
278
- $ python main.py --help
279
- usage: main.py [options]
280
-
281
- Options for main.py. Use command-line arguments (highest precedence) or environment variables.
282
-
283
- optiTo exclude the `markdownlint` rule start and end block, you can use the
284
- following syntax in your markdown file:STR_OPTION
285
- [env var: STR_OPTION] (required) (default: default value) (type: str): A string option
286
- -int_optRemember to replace `Your markdown content here` with your actual markdown
287
- content.(type: int): An int option
288
- -float_option FLOAT_OPTION, --float_option FLOAT_OPTION
289
- [env var: FLOAT_OPTION] (default: 1.0) (type: float): A float option
290
- -bool_option BOOL_OPTION, --bool_option BOOL_OPTION
291
- [env var: BOOL_OPTION] (required) (default: True) (type: bool): A bool option
292
- ```
293
-
294
- <!-- markdownlint-enable -->
295
-
296
- #### Input
297
-
298
- Capture the input data for the run.
299
-
300
- - Work with `JSON`inputs.
301
-
302
- ```python
303
- import nextmv
304
-
305
- # Read JSON from stdin.
306
- json_input_1 = nextmv.load_local()
307
- print(json_input_1.data)
308
-
309
- # Can also specify JSON format directly, and read from a file.
310
- json_input_2 = nextmv.load_local(input_format=nextmv.InputFormat.JSON, path="input.json")
311
- print(json_input_2.data)
312
- ```
313
-
314
- - Work with plain, `utf-8` encoded, text inputs.
315
-
316
- ```python
317
- import nextmv
318
-
319
- # Read text from stdin.
320
- text_input_1 = nextmv.load_local(input_format=nextmv.InputFormat.TEXT)
321
- print(text_input_1.data)
322
-
323
- # Can also read from a file.
324
- text_input_2 = nextmv.load_local(input_format=nextmv.InputFormat.TEXT, path="input.txt")
325
- print(text_input_2.data)
326
- ```
327
-
328
- <!-- markdownlint-disable -->
329
-
330
- - Work with multiple `CSV` files.
331
-
332
- ```python
333
- import nextmv
334
-
335
- # Read multiple CSV files from a dir named "input".
336
- csv_archive_input_1 = nextmv.load_local(input_format=nextmv.InputFormat.CSV_ARCHIVE)
337
- print(csv_archive_input_1.data)
338
-
339
- # Read multiple CSV files from a custom dir.
340
- csv_archive_input_2 = nextmv.load_local(input_format=nextmv.InputFormat.CSV_ARCHIVE, path="custom_dir")
341
- print(csv_archive_input_2.data)
342
- ```
343
-
344
- <!-- markdownlint-enable -->
345
-
346
- #### Logging
347
-
348
- The Nextmv platform captures logs via `stderr`. Use the provided functionality
349
- to record logs.
350
-
351
- ```python
352
- import sys
353
-
354
- import nextmv
355
-
356
- print("0. I do nothing")
357
-
358
- nextmv.redirect_stdout()
359
-
360
- nextmv.log("1. I log a message to stderr")
361
-
362
- print("2. I print a message to stdout")
363
-
364
- nextmv.reset_stdout()
365
-
366
- print("3. I print another message to stdout")
367
-
368
- print("4. I print yet another message to stderr without the logger", file=sys.stderr)
369
-
370
- nextmv.log("5. I log a message to stderr using the nextmv module directly")
371
-
372
- print("6. I print a message to stdout, again")
275
+ pip install nextmv
373
276
  ```
374
277
 
375
- After executing it, here are the messages printed to the different streams.
376
-
377
- - `stdout`
378
-
379
- ```txt
380
- 1. I do nothing
381
- 2. I print another message to stdout
382
- 3. I print a message to stdout, again
383
- ```
384
-
385
- - `stderr`
386
-
387
- ```txt
388
- 1. I log a message to stderr
389
- 2. I print a message to stdout
390
- 3. I print yet another message to stderr without the logger
391
- 4. I log a message to stderr using the nextmv module directly
392
- ```
393
-
394
- #### Output
395
-
396
- Write the output data after a run is completed.
397
-
398
- - Work with `JSON` outputs.
399
-
400
- ```python
401
- import nextmv
402
-
403
- output = nextmv.Output(
404
- solution={"foo": "bar"},
405
- statistics=nextmv.Statistics(
406
- result=nextmv.ResultStatistics(
407
- duration=1.0,
408
- value=2.0,
409
- custom={"custom": "result_value"},
410
- ),
411
- run=nextmv.RunStatistics(
412
- duration=3.0,
413
- iterations=4,
414
- custom={"custom": "run_value"},
415
- ),
416
- ),
417
- )
418
-
419
- # Write to stdout.
420
- nextmv.write_local(output)
421
-
422
- # Write to a file.
423
- nextmv.write_local(output, path="output.json")
424
- ```
425
-
426
- - Work with multple `CSV` files.
427
-
428
- ```python
429
- import nextmv
430
-
431
- output = nextmv.Output(
432
- output_format=nextmv.OutputFormat.CSV_ARCHIVE,
433
- solution={
434
- "output": [
435
- {"name": "Alice", "age": 30},
436
- {"name": "Bob", "age": 40},
437
- ],
438
- },
439
- statistics=nextmv.Statistics(
440
- result=nextmv.ResultStatistics(
441
- duration=1.0,
442
- value=2.0,
443
- custom={"custom": "result_value"},
444
- ),
445
- run=nextmv.RunStatistics(
446
- duration=3.0,
447
- iterations=4,
448
- custom={"custom": "run_value"},
449
- ),
450
- ),
451
- )
452
-
453
- # Write multiple CSV fiules to a dir named "output".
454
- nextmv.write_local(output)
455
-
456
- # Write multiple CSV files to a custom dir.
457
- nextmv.write_local(output, "custom_dir")
458
- ```
459
-
460
- ### Cloud
461
-
462
- Before starting:
463
-
464
- 1. [Sign up][signup] for a Nextmv account.
465
- 2. Get your API key. Go to [Team > API Key][api-key].
466
-
467
- Visit the [docs][docs] for more information. Make sure that you have your API
468
- key set as an environment variable:
278
+ Install all optional dependencies (recommended):
469
279
 
470
280
  ```bash
471
- export NEXTMV_API_KEY="<YOUR-API-KEY>"
281
+ pip install "nextmv[all]"
472
282
  ```
473
283
 
474
- Additionally, you must have a valid app in Nextmv Cloud.
475
-
476
- - Make a run and get the results.
477
-
478
- ```python
479
- import os
480
-
481
- from nextmv.cloud import Application, Client, PollingOptions
482
-
483
- input = {
484
- "defaults": {"vehicles": {"speed": 20}},
485
- "stops": [
486
- {
487
- "id": "Nijō Castle",
488
- "location": {"lon": 135.748134, "lat": 35.014239},
489
- "quantity": -1,
490
- },
491
- {
492
- "id": "Kyoto Imperial Palace",
493
- "location": {"lon": 135.762057, "lat": 35.025431},
494
- "quantity": -1,
495
- },
496
- ],
497
- "vehicles": [
498
- {
499
- "id": "v2",
500
- "capacity": 2,
501
- "start_location": {"lon": 135.728898, "lat": 35.039705},
502
- },
503
- ],
504
- }
505
-
506
- client = Client(api_key=os.getenv("NEXTMV_API_KEY"))
507
- app = Application(client=client, id="<YOUR-APP-ID>")
508
- result = app.new_run_with_result(
509
- input=input,
510
- instance_id="latest",
511
- run_options={"solve.duration": "1s"},
512
- polling_options=PollingOptions(), # Customize the polling options.
513
- )
514
- print(result.to_dict())
515
- ```
516
-
517
- [signup]: https://cloud.nextmv.io
518
- [docs]: https://nextmv.io/docs
519
- [api-key]: https://cloud.nextmv.io/team/api-keys
520
- [cloud]: #cloud
521
- [working-with-a-decision-model]: #working-with-a-decision-model
284
+ [docs]: https://nextmv-py.docs.nextmv.io/en/latest/nextmv/
@@ -0,0 +1,50 @@
1
+ nextmv/__about__.py,sha256=bQ5WltwnJ2DWtUa1Ur-mKSOXGWtA0PCrqR2GFguHyhw,24
2
+ nextmv/__entrypoint__.py,sha256=dA0iwwHtrq6Z9w9FxmxKLoBGLyhe7jWtUAU-Y3PEgHg,1094
3
+ nextmv/__init__.py,sha256=mC-gAzCdoZJ0BOVe2fDzKNdBtbXzx8XOxHP_7DdPMdQ,3857
4
+ nextmv/_serialization.py,sha256=jYitMS1MU8ldsmObT-K_8V8P2Wx69tnDiEHCCgPGun4,2834
5
+ nextmv/base_model.py,sha256=kPFqE-c_3LcEy8fY0qDrJk_gbPYgSKtetRMby71oxE8,2298
6
+ nextmv/deprecated.py,sha256=kEVfyQ-nT0v2ePXTNldjQG9uH5IlfQVy3L4tztIxwmU,1638
7
+ nextmv/input.py,sha256=XRjINb438rnjvQwjCXVOJ0UPa-xTnZc9xBYt0NLhjGw,39970
8
+ nextmv/logger.py,sha256=kNIbu46MisrzYe4T0hNMpWfRTKKacDVvbtQcNys_c_E,2513
9
+ nextmv/manifest.py,sha256=2c4DFO8tr9UftKJPocRBjg9z-LcpOZery5iTkX0u18Y,49103
10
+ nextmv/model.py,sha256=b323uAjr-eeChrIPLg4a8bnqOaoc12DQrQBnIPybd0k,14993
11
+ nextmv/options.py,sha256=rfQV0F5_it-L27wjqrs902wr4Q7sgSN7dw5o0c5sdEg,37842
12
+ nextmv/output.py,sha256=oqCnBvcYOZlvPSoX4trQ3EJR6GpE-4d0d7NDIq5hgL0,56008
13
+ nextmv/polling.py,sha256=Mka7tChVR7Ws-Hg9W-Yzo7wthhVg-Qp-FK54E70Fzdw,9711
14
+ nextmv/run.py,sha256=N5qbfEJ_p5rmIwhFkiWRtGMU_u209hJ4_b-xKrD70-k,52284
15
+ nextmv/safe.py,sha256=VAK4fGEurbLNji4Pg5Okga5XQSbI4aI9JJf95_68Z20,3867
16
+ nextmv/status.py,sha256=SCDLhh2om3yeO5FxO0x-_RShQsZNXEpjHNdCGdb3VUI,2787
17
+ nextmv/cloud/__init__.py,sha256=2wI72lhWq81BYv1OpS0OOTT5-3sivpX0H4z5ANPoLMc,5051
18
+ nextmv/cloud/acceptance_test.py,sha256=fZdp4O6pZrl7TaiUrTFPp7O4VJt-4R_W2yo4s8UAS5I,27691
19
+ nextmv/cloud/account.py,sha256=jIdGNyI3l3dVh2PuriAwAOrEuWRM150WgzxcBMVBNRw,6058
20
+ nextmv/cloud/application.py,sha256=29Tr7jWwa369ejkgFX3VXU_G3VK-2ATyL6Ma5tGXfAg,139592
21
+ nextmv/cloud/batch_experiment.py,sha256=IwvXjapauTkrYzmJhM5DeHBpxSA49MewQA4Pjk1KWzw,10339
22
+ nextmv/cloud/client.py,sha256=Yj4FE4GKsLHkYijAYXcotlyNfhAWANMuWetHXsYPg1M,18101
23
+ nextmv/cloud/ensemble.py,sha256=_hKPjSLtuGH1xGG70ZBsmY_IL5XinZqVHHwBxtX9Omw,8570
24
+ nextmv/cloud/input_set.py,sha256=wsLmMI1C7BslWDN5j1RnVUA8z54-Hq1eLG9bkzyqafo,4187
25
+ nextmv/cloud/instance.py,sha256=n68CGzv0vfTyM-IP3zoiSk6x5Kusn9taYpV-dSEhh6M,3987
26
+ nextmv/cloud/package.py,sha256=7qN09uJ8LyfDhPPo-eeScjuZHTp8mLY1LO1NVo1YNT4,15223
27
+ nextmv/cloud/scenario.py,sha256=1_4PI9ehYaSonEe_l59cFhZNmqQ_brXXP6-mVq9i8a8,14183
28
+ nextmv/cloud/secrets.py,sha256=fA5cX0jfTsPVZWV7433wzETGlXpWRLHGswuObx9e6FQ,6820
29
+ nextmv/cloud/url.py,sha256=Fz70ywkWdCLmP21ZBmJwZi5kDbjpmsX_VlwVF_xQeHg,1836
30
+ nextmv/cloud/version.py,sha256=5_S7_pWUVBFbvAArku20eK7S645GJcHtgE2OpXLdSzQ,5300
31
+ nextmv/default_app/.gitignore,sha256=gsfnfXMYNt-YTroh5hAzauwBZoPDJ6D_fB17rMSnIko,8
32
+ nextmv/default_app/README.md,sha256=SroGwvWiDTz12yctMfviFYw7z1EMU_72ESK2dyt-Ypg,664
33
+ nextmv/default_app/app.yaml,sha256=TKjKnuoK0SDpouB_AS7TQmE_8HZbQYjmwFvhzFL1xpc,382
34
+ nextmv/default_app/input.json,sha256=zgvbKL3boB0WIU6-9mEU3ZWBddQ5cQ0vhgmDwDyz4hE,63
35
+ nextmv/default_app/main.py,sha256=gG-1JIvKXPCkm4JV46PcXxsQTAefwPXQbdPxkSubhf0,888
36
+ nextmv/default_app/requirements.txt,sha256=wRE_HkYYWzCGnYZ2NuatHXul4gCHvU3iUAdsxtzpYiA,29
37
+ nextmv/default_app/src/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
+ nextmv/default_app/src/main.py,sha256=WWeN_xl_mcPhICl3rSCvdEjRkFXGmAnej88FhS-fAmc,884
39
+ nextmv/default_app/src/visuals.py,sha256=WYK_YBnLmYo3TpVev1CpoNCuW5R7hk9QIkeCmvMn1Fs,1014
40
+ nextmv/local/__init__.py,sha256=6BsoqlK4dw6X11_uKzz9gBPfxKpdiol2FYO8R3X73SE,116
41
+ nextmv/local/application.py,sha256=RtqKR3yRI2GFn_RLyaRZMWZW30BuYllLdAY2OsPL7Xc,48245
42
+ nextmv/local/executor.py,sha256=g9Bjjm8EzF2wOd0NSow1r_O_L7UBmuFYUYYCOdmapAw,36491
43
+ nextmv/local/geojson_handler.py,sha256=7FavJdkUonop-yskjis0x3qFGB8A5wZyoBUblw-bVhw,12540
44
+ nextmv/local/local.py,sha256=cp56UpI8h19Ob6Jvb_Ni0ceXH5Vv3ET_iPTDe6ftq3Y,2617
45
+ nextmv/local/plotly_handler.py,sha256=bLb50e3AkVr_W-F6S7lXfeRdN60mG2jk3UElNmhoMWU,1930
46
+ nextmv/local/runner.py,sha256=Fa-G4g5yaBgLeBfYU-ePs65Q3Ses_xYvXGhPtHpAkrU,8546
47
+ nextmv-0.35.0.dist-info/METADATA,sha256=2gDLgPS0t_kLacTwUmza1FKUTK_MIv8a5CTdP4soyAQ,15960
48
+ nextmv-0.35.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
49
+ nextmv-0.35.0.dist-info/licenses/LICENSE,sha256=ZIbK-sSWA-OZprjNbmJAglYRtl5_K4l9UwAV3PGJAPc,11349
50
+ nextmv-0.35.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.25.0
2
+ Generator: hatchling 1.27.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any