nextmv 0.29.5.dev1__py3-none-any.whl → 0.31.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nextmv/__about__.py +1 -1
- nextmv/__init__.py +40 -0
- nextmv/cloud/__init__.py +39 -30
- nextmv/cloud/acceptance_test.py +2 -51
- nextmv/cloud/account.py +1 -1
- nextmv/cloud/application.py +599 -516
- nextmv/cloud/batch_experiment.py +73 -1
- nextmv/cloud/input_set.py +1 -1
- nextmv/cloud/package.py +1 -1
- nextmv/cloud/url.py +73 -0
- nextmv/default_app/.gitignore +1 -0
- nextmv/default_app/app.yaml +2 -0
- nextmv/default_app/src/main.py +2 -1
- nextmv/input.py +17 -1
- nextmv/local/__init__.py +5 -0
- nextmv/local/application.py +1147 -0
- nextmv/local/executor.py +718 -0
- nextmv/local/geojson_handler.py +323 -0
- nextmv/local/plotly_handler.py +61 -0
- nextmv/local/runner.py +312 -0
- nextmv/{cloud/manifest.py → manifest.py} +258 -54
- nextmv/output.py +61 -8
- nextmv/polling.py +287 -0
- nextmv/{cloud/run.py → run.py} +390 -53
- nextmv/{cloud/safe.py → safe.py} +35 -3
- nextmv/{cloud/status.py → status.py} +9 -9
- {nextmv-0.29.5.dev1.dist-info → nextmv-0.31.0.dist-info}/METADATA +5 -1
- nextmv-0.31.0.dist-info/RECORD +46 -0
- nextmv-0.29.5.dev1.dist-info/RECORD +0 -37
- {nextmv-0.29.5.dev1.dist-info → nextmv-0.31.0.dist-info}/WHEEL +0 -0
- {nextmv-0.29.5.dev1.dist-info → nextmv-0.31.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""
|
|
2
|
+
Module with the logic for handling an app manifest.
|
|
2
3
|
|
|
3
4
|
This module provides classes and functions for managing Nextmv app manifests.
|
|
4
5
|
Manifest files (app.yaml) define how an application is built, run, and deployed
|
|
5
|
-
on the Nextmv
|
|
6
|
+
on the Nextmv platform.
|
|
6
7
|
|
|
7
8
|
Classes
|
|
8
9
|
-------
|
|
9
10
|
ManifestType
|
|
10
11
|
Enum for application types based on programming language.
|
|
11
12
|
ManifestRuntime
|
|
12
|
-
Enum for runtime environments where apps run on Nextmv
|
|
13
|
+
Enum for runtime environments where apps run on Nextmv.
|
|
13
14
|
ManifestBuild
|
|
14
15
|
Class for build-specific attributes in the manifest.
|
|
15
16
|
ManifestPythonModel
|
|
@@ -24,14 +25,22 @@ ManifestOptions
|
|
|
24
25
|
Class containing a list of options for the decision model.
|
|
25
26
|
ManifestValidation
|
|
26
27
|
Class for validation rules for options in the manifest.
|
|
28
|
+
ManifestContentMultiFileInput
|
|
29
|
+
Class for multi-file content format input configuration.
|
|
30
|
+
ManifestContentMultiFileOutput
|
|
31
|
+
Class for multi-file content format output configuration.
|
|
32
|
+
ManifestContentMultiFile
|
|
33
|
+
Class for multi-file content format configuration.
|
|
34
|
+
ManifestContent
|
|
35
|
+
Class for content configuration specifying how app input/output is handled.
|
|
27
36
|
ManifestConfiguration
|
|
28
37
|
Class for configuration settings for the decision model.
|
|
29
38
|
Manifest
|
|
30
|
-
Main class representing an app manifest for Nextmv
|
|
39
|
+
Main class representing an app manifest for Nextmv.
|
|
31
40
|
|
|
32
41
|
Constants
|
|
33
42
|
--------
|
|
34
|
-
|
|
43
|
+
MANIFEST_FILE_NAME
|
|
35
44
|
Name of the app manifest file.
|
|
36
45
|
"""
|
|
37
46
|
|
|
@@ -43,6 +52,7 @@ import yaml
|
|
|
43
52
|
from pydantic import AliasChoices, Field
|
|
44
53
|
|
|
45
54
|
from nextmv.base_model import BaseModel
|
|
55
|
+
from nextmv.input import InputFormat
|
|
46
56
|
from nextmv.model import _REQUIREMENTS_FILE, ModelConfiguration
|
|
47
57
|
from nextmv.options import Option, Options, OptionsEnforcement
|
|
48
58
|
|
|
@@ -51,10 +61,10 @@ MANIFEST_FILE_NAME = "app.yaml"
|
|
|
51
61
|
|
|
52
62
|
This constant defines the standard filename for Nextmv app manifest files.
|
|
53
63
|
|
|
54
|
-
You can import the `
|
|
64
|
+
You can import the `MANIFEST_FILE_NAME` constant directly from `nextmv`:
|
|
55
65
|
|
|
56
66
|
```python
|
|
57
|
-
from nextmv
|
|
67
|
+
from nextmv import MANIFEST_FILE_NAME
|
|
58
68
|
```
|
|
59
69
|
|
|
60
70
|
Notes
|
|
@@ -67,10 +77,10 @@ class ManifestType(str, Enum):
|
|
|
67
77
|
"""
|
|
68
78
|
Type of application in the manifest, based on the programming language.
|
|
69
79
|
|
|
70
|
-
You can import the `ManifestType` class directly from `
|
|
80
|
+
You can import the `ManifestType` class directly from `nextmv`:
|
|
71
81
|
|
|
72
82
|
```python
|
|
73
|
-
from nextmv
|
|
83
|
+
from nextmv import ManifestType
|
|
74
84
|
```
|
|
75
85
|
|
|
76
86
|
This enum defines the supported programming languages for applications
|
|
@@ -87,7 +97,7 @@ class ManifestType(str, Enum):
|
|
|
87
97
|
|
|
88
98
|
Examples
|
|
89
99
|
--------
|
|
90
|
-
>>> from nextmv
|
|
100
|
+
>>> from nextmv import ManifestType
|
|
91
101
|
>>> manifest_type = ManifestType.PYTHON
|
|
92
102
|
>>> manifest_type
|
|
93
103
|
<ManifestType.PYTHON: 'python'>
|
|
@@ -107,10 +117,10 @@ class ManifestRuntime(str, Enum):
|
|
|
107
117
|
"""
|
|
108
118
|
Runtime (environment) where the app will be run on Nextmv Cloud.
|
|
109
119
|
|
|
110
|
-
You can import the `ManifestRuntime` class directly from `
|
|
120
|
+
You can import the `ManifestRuntime` class directly from `nextmv`:
|
|
111
121
|
|
|
112
122
|
```python
|
|
113
|
-
from nextmv
|
|
123
|
+
from nextmv import ManifestRuntime
|
|
114
124
|
```
|
|
115
125
|
|
|
116
126
|
This enum defines the supported runtime environments for applications
|
|
@@ -132,7 +142,7 @@ class ManifestRuntime(str, Enum):
|
|
|
132
142
|
|
|
133
143
|
Examples
|
|
134
144
|
--------
|
|
135
|
-
>>> from nextmv
|
|
145
|
+
>>> from nextmv import ManifestRuntime
|
|
136
146
|
>>> runtime = ManifestRuntime.PYTHON
|
|
137
147
|
>>> runtime
|
|
138
148
|
<ManifestRuntime.PYTHON: 'ghcr.io/nextmv-io/runtime/python:3.11'>
|
|
@@ -162,10 +172,10 @@ class ManifestBuild(BaseModel):
|
|
|
162
172
|
"""
|
|
163
173
|
Build-specific attributes.
|
|
164
174
|
|
|
165
|
-
You can import the `ManifestBuild` class directly from `
|
|
175
|
+
You can import the `ManifestBuild` class directly from `nextmv`:
|
|
166
176
|
|
|
167
177
|
```python
|
|
168
|
-
from nextmv
|
|
178
|
+
from nextmv import ManifestBuild
|
|
169
179
|
```
|
|
170
180
|
|
|
171
181
|
Parameters
|
|
@@ -181,7 +191,7 @@ class ManifestBuild(BaseModel):
|
|
|
181
191
|
|
|
182
192
|
Examples
|
|
183
193
|
--------
|
|
184
|
-
>>> from nextmv
|
|
194
|
+
>>> from nextmv import ManifestBuild
|
|
185
195
|
>>> build_config = ManifestBuild(
|
|
186
196
|
... command="make build",
|
|
187
197
|
... environment={"DEBUG": "true"}
|
|
@@ -215,7 +225,7 @@ class ManifestBuild(BaseModel):
|
|
|
215
225
|
|
|
216
226
|
Examples
|
|
217
227
|
--------
|
|
218
|
-
>>> from nextmv
|
|
228
|
+
>>> from nextmv import ManifestBuild
|
|
219
229
|
>>> build_config = ManifestBuild(environment={"COUNT": 1, "NAME": "test"})
|
|
220
230
|
>>> build_config.environment_to_dict()
|
|
221
231
|
{'COUNT': '1', 'NAME': 'test'}
|
|
@@ -234,10 +244,10 @@ class ManifestPythonModel(BaseModel):
|
|
|
234
244
|
"""
|
|
235
245
|
Model-specific instructions for a Python app.
|
|
236
246
|
|
|
237
|
-
You can import the `ManifestPythonModel` class directly from `
|
|
247
|
+
You can import the `ManifestPythonModel` class directly from `nextmv`:
|
|
238
248
|
|
|
239
249
|
```python
|
|
240
|
-
from nextmv
|
|
250
|
+
from nextmv import ManifestPythonModel
|
|
241
251
|
```
|
|
242
252
|
|
|
243
253
|
Parameters
|
|
@@ -252,7 +262,7 @@ class ManifestPythonModel(BaseModel):
|
|
|
252
262
|
|
|
253
263
|
Examples
|
|
254
264
|
--------
|
|
255
|
-
>>> from nextmv
|
|
265
|
+
>>> from nextmv import ManifestPythonModel
|
|
256
266
|
>>> python_model_config = ManifestPythonModel(
|
|
257
267
|
... name="routing_model",
|
|
258
268
|
... options=[{"name": "max_vehicles", "type": "int", "default": 10}]
|
|
@@ -276,10 +286,10 @@ class ManifestPython(BaseModel):
|
|
|
276
286
|
"""
|
|
277
287
|
Python-specific instructions.
|
|
278
288
|
|
|
279
|
-
You can import the `ManifestPython` class directly from `
|
|
289
|
+
You can import the `ManifestPython` class directly from `nextmv`:
|
|
280
290
|
|
|
281
291
|
```python
|
|
282
|
-
from nextmv
|
|
292
|
+
from nextmv import ManifestPython
|
|
283
293
|
```
|
|
284
294
|
|
|
285
295
|
Parameters
|
|
@@ -296,7 +306,7 @@ class ManifestPython(BaseModel):
|
|
|
296
306
|
|
|
297
307
|
Examples
|
|
298
308
|
--------
|
|
299
|
-
>>> from nextmv
|
|
309
|
+
>>> from nextmv import ManifestPython, ManifestPythonModel
|
|
300
310
|
>>> python_config = ManifestPython(
|
|
301
311
|
... pip_requirements="requirements.txt",
|
|
302
312
|
... model=ManifestPythonModel(name="my_model")
|
|
@@ -327,10 +337,10 @@ class ManifestOptionUI(BaseModel):
|
|
|
327
337
|
"""
|
|
328
338
|
UI attributes for an option in the manifest.
|
|
329
339
|
|
|
330
|
-
You can import the `ManifestOptionUI` class directly from `
|
|
340
|
+
You can import the `ManifestOptionUI` class directly from `nextmv`:
|
|
331
341
|
|
|
332
342
|
```python
|
|
333
|
-
from nextmv
|
|
343
|
+
from nextmv import ManifestOptionUI
|
|
334
344
|
```
|
|
335
345
|
|
|
336
346
|
Parameters
|
|
@@ -342,7 +352,7 @@ class ManifestOptionUI(BaseModel):
|
|
|
342
352
|
"toggle". This attribute is not used in the local `Options` class, but
|
|
343
353
|
it is used in the Nextmv Cloud UI to define the type of control to use for
|
|
344
354
|
the option. This will be validated by the Nextmv Cloud, and availability
|
|
345
|
-
is based on
|
|
355
|
+
is based on option_type.
|
|
346
356
|
hidden_from : list[str], optional
|
|
347
357
|
A list of team roles to which this option will be hidden in the UI. For
|
|
348
358
|
example, if you want to hide an option from the "operator" role, you can
|
|
@@ -353,7 +363,7 @@ class ManifestOptionUI(BaseModel):
|
|
|
353
363
|
|
|
354
364
|
Examples
|
|
355
365
|
--------
|
|
356
|
-
>>> from nextmv
|
|
366
|
+
>>> from nextmv import ManifestOptionUI
|
|
357
367
|
>>> ui_config = ManifestOptionUI(control_type="input")
|
|
358
368
|
>>> ui_config.control_type
|
|
359
369
|
'input'
|
|
@@ -373,10 +383,10 @@ class ManifestOption(BaseModel):
|
|
|
373
383
|
"""
|
|
374
384
|
An option for the decision model that is recorded in the manifest.
|
|
375
385
|
|
|
376
|
-
You can import the `ManifestOption` class directly from `
|
|
386
|
+
You can import the `ManifestOption` class directly from `nextmv`:
|
|
377
387
|
|
|
378
388
|
```python
|
|
379
|
-
from nextmv
|
|
389
|
+
from nextmv import ManifestOption
|
|
380
390
|
```
|
|
381
391
|
|
|
382
392
|
Parameters
|
|
@@ -408,7 +418,7 @@ class ManifestOption(BaseModel):
|
|
|
408
418
|
|
|
409
419
|
Examples
|
|
410
420
|
--------
|
|
411
|
-
>>> from nextmv
|
|
421
|
+
>>> from nextmv import ManifestOption
|
|
412
422
|
>>> option = ManifestOption(
|
|
413
423
|
... name="solve.duration",
|
|
414
424
|
... option_type="string",
|
|
@@ -461,7 +471,7 @@ class ManifestOption(BaseModel):
|
|
|
461
471
|
Examples
|
|
462
472
|
--------
|
|
463
473
|
>>> from nextmv.options import Option
|
|
464
|
-
>>> from nextmv
|
|
474
|
+
>>> from nextmv import ManifestOption
|
|
465
475
|
>>> sdk_option = Option(name="max_stops", option_type=int, default=100)
|
|
466
476
|
>>> manifest_opt = ManifestOption.from_option(sdk_option)
|
|
467
477
|
>>> manifest_opt.name
|
|
@@ -513,7 +523,7 @@ class ManifestOption(BaseModel):
|
|
|
513
523
|
|
|
514
524
|
Examples
|
|
515
525
|
--------
|
|
516
|
-
>>> from nextmv
|
|
526
|
+
>>> from nextmv import ManifestOption
|
|
517
527
|
>>> manifest_opt = ManifestOption(name="max_stops", option_type="int", default=100)
|
|
518
528
|
>>> sdk_option = manifest_opt.to_option()
|
|
519
529
|
>>> sdk_option.name
|
|
@@ -551,10 +561,10 @@ class ManifestValidation(BaseModel):
|
|
|
551
561
|
"""
|
|
552
562
|
Validation rules for options in the manifest.
|
|
553
563
|
|
|
554
|
-
You can import the `ManifestValidation` class directly from `
|
|
564
|
+
You can import the `ManifestValidation` class directly from `nextmv`:
|
|
555
565
|
|
|
556
566
|
```python
|
|
557
|
-
from nextmv
|
|
567
|
+
from nextmv import ManifestValidation
|
|
558
568
|
```
|
|
559
569
|
|
|
560
570
|
Parameters
|
|
@@ -568,7 +578,7 @@ class ManifestValidation(BaseModel):
|
|
|
568
578
|
|
|
569
579
|
Examples
|
|
570
580
|
--------
|
|
571
|
-
>>> from nextmv
|
|
581
|
+
>>> from nextmv import ManifestValidation
|
|
572
582
|
>>> validation = ManifestValidation(enforce="all")
|
|
573
583
|
>>> validation.enforce
|
|
574
584
|
'all'
|
|
@@ -587,10 +597,10 @@ class ManifestOptions(BaseModel):
|
|
|
587
597
|
"""
|
|
588
598
|
Options for the decision model.
|
|
589
599
|
|
|
590
|
-
You can import the `ManifestOptions` class directly from `
|
|
600
|
+
You can import the `ManifestOptions` class directly from `nextmv`:
|
|
591
601
|
|
|
592
602
|
```python
|
|
593
|
-
from nextmv
|
|
603
|
+
from nextmv import ManifestOptions
|
|
594
604
|
```
|
|
595
605
|
|
|
596
606
|
Parameters
|
|
@@ -602,7 +612,7 @@ class ManifestOptions(BaseModel):
|
|
|
602
612
|
is a parameter that configures the decision model.
|
|
603
613
|
validation: Optional[ManifestValidation], default=None
|
|
604
614
|
Optional validation rules for all options.
|
|
605
|
-
format: Optional[list[str]], default=None
|
|
615
|
+
format : Optional[list[str]], default=None
|
|
606
616
|
A list of strings that define how options are transformed into command
|
|
607
617
|
line arguments. Use `{{name}}` to refer to the option name and
|
|
608
618
|
`{{value}}` to refer to the option value.
|
|
@@ -610,7 +620,7 @@ class ManifestOptions(BaseModel):
|
|
|
610
620
|
|
|
611
621
|
Examples
|
|
612
622
|
--------
|
|
613
|
-
>>> from nextmv
|
|
623
|
+
>>> from nextmv import ManifestOptions, ManifestOption
|
|
614
624
|
>>> options_config = ManifestOptions(
|
|
615
625
|
... strict=True,
|
|
616
626
|
... validation=ManifestValidation(enforce="all"),
|
|
@@ -676,7 +686,7 @@ class ManifestOptions(BaseModel):
|
|
|
676
686
|
Examples
|
|
677
687
|
--------
|
|
678
688
|
>>> from nextmv.options import Options, Option
|
|
679
|
-
>>> from nextmv
|
|
689
|
+
>>> from nextmv import ManifestOptions
|
|
680
690
|
>>> sdk_options = Options(Option("max_vehicles", int, 5))
|
|
681
691
|
>>> manifest_options = ManifestOptions.from_options(sdk_options)
|
|
682
692
|
>>> manifest_options.items[0].name
|
|
@@ -692,14 +702,176 @@ class ManifestOptions(BaseModel):
|
|
|
692
702
|
)
|
|
693
703
|
|
|
694
704
|
|
|
705
|
+
class ManifestContentMultiFileInput(BaseModel):
|
|
706
|
+
"""
|
|
707
|
+
Configuration for multi-file content format input.
|
|
708
|
+
|
|
709
|
+
You can import the `ManifestContentMultiFileInput` class directly from `nextmv`:
|
|
710
|
+
|
|
711
|
+
```python
|
|
712
|
+
from nextmv import ManifestContentMultiFileInput
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
Parameters
|
|
716
|
+
----------
|
|
717
|
+
path : str
|
|
718
|
+
The path to the input file or directory.
|
|
719
|
+
|
|
720
|
+
|
|
721
|
+
Examples
|
|
722
|
+
--------
|
|
723
|
+
>>> from nextmv import ManifestContentMultiFileInput
|
|
724
|
+
>>> input_config = ManifestContentMultiFileInput(path="data/input/")
|
|
725
|
+
>>> input_config.path
|
|
726
|
+
'data/input/'
|
|
727
|
+
"""
|
|
728
|
+
|
|
729
|
+
path: str
|
|
730
|
+
"""The path to the input file or directory."""
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
class ManifestContentMultiFileOutput(BaseModel):
|
|
734
|
+
"""
|
|
735
|
+
Configuration for multi-file content format output.
|
|
736
|
+
|
|
737
|
+
You can import the `ManifestContentMultiFileOutput` class directly from `nextmv`:
|
|
738
|
+
|
|
739
|
+
```python
|
|
740
|
+
from nextmv import ManifestContentMultiFileOutput
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
Parameters
|
|
744
|
+
----------
|
|
745
|
+
statistics : Optional[str], default=""
|
|
746
|
+
The path to the statistics file.
|
|
747
|
+
assets : Optional[str], default=""
|
|
748
|
+
The path to the assets file.
|
|
749
|
+
solutions : Optional[str], default=""
|
|
750
|
+
The path to the solutions directory.
|
|
751
|
+
|
|
752
|
+
Examples
|
|
753
|
+
--------
|
|
754
|
+
>>> from nextmv import ManifestContentMultiFileOutput
|
|
755
|
+
>>> output_config = ManifestContentMultiFileOutput(
|
|
756
|
+
... statistics="my-outputs/statistics.json",
|
|
757
|
+
... assets="my-outputs/assets.json",
|
|
758
|
+
... solutions="my-outputs/solutions/"
|
|
759
|
+
... )
|
|
760
|
+
>>> output_config.statistics
|
|
761
|
+
'my-outputs/statistics.json'
|
|
762
|
+
"""
|
|
763
|
+
|
|
764
|
+
statistics: Optional[str] = ""
|
|
765
|
+
"""The path to the statistics file."""
|
|
766
|
+
assets: Optional[str] = ""
|
|
767
|
+
"""The path to the assets file."""
|
|
768
|
+
solutions: Optional[str] = ""
|
|
769
|
+
"""The path to the solutions directory."""
|
|
770
|
+
|
|
771
|
+
|
|
772
|
+
class ManifestContentMultiFile(BaseModel):
|
|
773
|
+
"""
|
|
774
|
+
Configuration for multi-file content format.
|
|
775
|
+
|
|
776
|
+
You can import the `ManifestContentMultiFile` class directly from `nextmv`:
|
|
777
|
+
|
|
778
|
+
```python
|
|
779
|
+
from nextmv import ManifestContentMultiFile
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
Parameters
|
|
783
|
+
----------
|
|
784
|
+
input : ManifestContentMultiFileInput
|
|
785
|
+
Configuration for multi-file content format input.
|
|
786
|
+
output : ManifestContentMultiFileOutput
|
|
787
|
+
Configuration for multi-file content format output.
|
|
788
|
+
|
|
789
|
+
Examples
|
|
790
|
+
--------
|
|
791
|
+
>>> from nextmv import ManifestContentMultiFile, ManifestContentMultiFileInput, ManifestContentMultiFileOutput
|
|
792
|
+
>>> multi_file_config = ManifestContentMultiFile(
|
|
793
|
+
... input=ManifestContentMultiFileInput(path="data/input/"),
|
|
794
|
+
... output=ManifestContentMultiFileOutput(
|
|
795
|
+
... statistics="my-outputs/statistics.json",
|
|
796
|
+
... assets="my-outputs/assets.json",
|
|
797
|
+
... solutions="my-outputs/solutions/"
|
|
798
|
+
... )
|
|
799
|
+
... )
|
|
800
|
+
>>> multi_file_config.input.path
|
|
801
|
+
'data/input/'
|
|
802
|
+
|
|
803
|
+
"""
|
|
804
|
+
|
|
805
|
+
input: ManifestContentMultiFileInput
|
|
806
|
+
"""Configuration for multi-file content format input."""
|
|
807
|
+
output: ManifestContentMultiFileOutput
|
|
808
|
+
"""Configuration for multi-file content format output."""
|
|
809
|
+
|
|
810
|
+
|
|
811
|
+
class ManifestContent(BaseModel):
|
|
812
|
+
"""
|
|
813
|
+
Content configuration for specifying how the app input/output is handled.
|
|
814
|
+
|
|
815
|
+
You can import the `ManifestContent` class directly from `nextmv`:
|
|
816
|
+
|
|
817
|
+
```python
|
|
818
|
+
from nextmv import ManifestContent
|
|
819
|
+
```
|
|
820
|
+
|
|
821
|
+
Parameters
|
|
822
|
+
----------
|
|
823
|
+
format : str
|
|
824
|
+
The format of the content. Must be one of "json", "multi-file", or "csv-archive".
|
|
825
|
+
multi_file : Optional[ManifestContentMultiFile], default=None
|
|
826
|
+
Configuration for multi-file content format.
|
|
827
|
+
|
|
828
|
+
Examples
|
|
829
|
+
--------
|
|
830
|
+
>>> from nextmv import ManifestContent
|
|
831
|
+
>>> content_config = ManifestContent(
|
|
832
|
+
... format="multi-file",
|
|
833
|
+
... multi_file=ManifestContentMultiFile(
|
|
834
|
+
... input=ManifestContentMultiFileInput(path="data/input/"),
|
|
835
|
+
... output=ManifestContentMultiFileOutput(
|
|
836
|
+
... statistics="my-outputs/statistics.json",
|
|
837
|
+
... assets="my-outputs/assets.json",
|
|
838
|
+
... solutions="my-outputs/solutions/"
|
|
839
|
+
... )
|
|
840
|
+
... )
|
|
841
|
+
... )
|
|
842
|
+
>>> content_config.format
|
|
843
|
+
'multi-file'
|
|
844
|
+
>>> content_config.multi_file.input.path
|
|
845
|
+
'data/input/'
|
|
846
|
+
"""
|
|
847
|
+
|
|
848
|
+
format: InputFormat
|
|
849
|
+
"""
|
|
850
|
+
The format of the content. Can only be `InputFormat.JSON`,
|
|
851
|
+
`InputFormat.MULTI_FILE`, or `InputFormat.CSV_ARCHIVE`.
|
|
852
|
+
"""
|
|
853
|
+
multi_file: Optional[ManifestContentMultiFile] = Field(
|
|
854
|
+
serialization_alias="multi-file",
|
|
855
|
+
validation_alias=AliasChoices("multi-file", "multi_file"),
|
|
856
|
+
default=None,
|
|
857
|
+
)
|
|
858
|
+
"""Configuration for multi-file content format."""
|
|
859
|
+
|
|
860
|
+
def model_post_init(self, __context) -> None:
|
|
861
|
+
"""Post-initialization to validate fields."""
|
|
862
|
+
acceptable_formats = [InputFormat.JSON, InputFormat.MULTI_FILE, InputFormat.CSV_ARCHIVE]
|
|
863
|
+
if self.format not in acceptable_formats:
|
|
864
|
+
raise ValueError(f"Invalid format: {self.format}. Must be one of {acceptable_formats}.")
|
|
865
|
+
|
|
866
|
+
|
|
695
867
|
class ManifestConfiguration(BaseModel):
|
|
696
868
|
"""
|
|
697
869
|
Configuration for the decision model.
|
|
698
870
|
|
|
699
|
-
You can import the `ManifestConfiguration` class directly from `
|
|
871
|
+
You can import the `ManifestConfiguration` class directly from `nextmv`:
|
|
700
872
|
|
|
701
873
|
```python
|
|
702
|
-
from nextmv
|
|
874
|
+
from nextmv import ManifestConfiguration
|
|
703
875
|
```
|
|
704
876
|
|
|
705
877
|
Parameters
|
|
@@ -709,7 +881,7 @@ class ManifestConfiguration(BaseModel):
|
|
|
709
881
|
|
|
710
882
|
Examples
|
|
711
883
|
--------
|
|
712
|
-
>>> from nextmv
|
|
884
|
+
>>> from nextmv import ManifestConfiguration, ManifestOptions, ManifestOption
|
|
713
885
|
>>> model_config = ManifestConfiguration(
|
|
714
886
|
... options=ManifestOptions(
|
|
715
887
|
... items=[ManifestOption(name="debug_mode", option_type="bool", default=False)]
|
|
@@ -719,18 +891,20 @@ class ManifestConfiguration(BaseModel):
|
|
|
719
891
|
'debug_mode'
|
|
720
892
|
"""
|
|
721
893
|
|
|
722
|
-
options: ManifestOptions
|
|
894
|
+
options: Optional[ManifestOptions] = None
|
|
723
895
|
"""Options for the decision model."""
|
|
896
|
+
content: Optional[ManifestContent] = None
|
|
897
|
+
"""Content configuration for specifying how the app input/output is handled."""
|
|
724
898
|
|
|
725
899
|
|
|
726
900
|
class Manifest(BaseModel):
|
|
727
901
|
"""
|
|
728
902
|
Represents an app manifest (`app.yaml`) for Nextmv Cloud.
|
|
729
903
|
|
|
730
|
-
You can import the `Manifest` class directly from `
|
|
904
|
+
You can import the `Manifest` class directly from `nextmv`:
|
|
731
905
|
|
|
732
906
|
```python
|
|
733
|
-
from nextmv
|
|
907
|
+
from nextmv import Manifest
|
|
734
908
|
```
|
|
735
909
|
|
|
736
910
|
An application that runs on the Nextmv Platform must contain a file named
|
|
@@ -772,10 +946,16 @@ class Manifest(BaseModel):
|
|
|
772
946
|
configuration : Optional[ManifestConfiguration], default=None
|
|
773
947
|
A list of options for the decision model. An option is a
|
|
774
948
|
parameter that configures the decision model.
|
|
949
|
+
entrypoint : Optional[str], default=None
|
|
950
|
+
Optional entrypoint for the decision model. When not specified, the
|
|
951
|
+
following default entrypoints are used, according to the `.runtime`:
|
|
952
|
+
- `ManifestRuntime.PYTHON`, `ManifestRuntime.HEXALY`, `ManifestRuntime.PYOMO`: `./main.py`
|
|
953
|
+
- `ManifestRuntime.DEFAULT`: `./main`
|
|
954
|
+
- Java: `./main.jar`
|
|
775
955
|
|
|
776
956
|
Examples
|
|
777
957
|
--------
|
|
778
|
-
>>> from nextmv
|
|
958
|
+
>>> from nextmv import Manifest, ManifestRuntime, ManifestType
|
|
779
959
|
>>> manifest = Manifest(
|
|
780
960
|
... files=["main.py", "model_logic/"],
|
|
781
961
|
... runtime=ManifestRuntime.PYTHON,
|
|
@@ -833,6 +1013,29 @@ class Manifest(BaseModel):
|
|
|
833
1013
|
Configuration for the decision model. A list of options for the decision
|
|
834
1014
|
model. An option is a parameter that configures the decision model.
|
|
835
1015
|
"""
|
|
1016
|
+
entrypoint: Optional[str] = None
|
|
1017
|
+
"""
|
|
1018
|
+
Optional entrypoint for the decision model. When not specified, the
|
|
1019
|
+
following default entrypoints are used, according to the `.runtime`:
|
|
1020
|
+
|
|
1021
|
+
- `ManifestRuntime.PYTHON`, `ManifestRuntime.HEXALY`, `ManifestRuntime.PYOMO`: `./main.py`
|
|
1022
|
+
- `ManifestRuntime.DEFAULT`: `./main`
|
|
1023
|
+
- Java: `./main.jar`
|
|
1024
|
+
"""
|
|
1025
|
+
|
|
1026
|
+
def model_post_init(self, __context) -> None:
|
|
1027
|
+
if self.entrypoint is None:
|
|
1028
|
+
if self.runtime in (ManifestRuntime.PYTHON, ManifestRuntime.HEXALY, ManifestRuntime.PYOMO):
|
|
1029
|
+
self.entrypoint = "./main.py"
|
|
1030
|
+
elif self.runtime == ManifestRuntime.DEFAULT:
|
|
1031
|
+
self.entrypoint = "./main"
|
|
1032
|
+
elif self.runtime == ManifestRuntime.JAVA:
|
|
1033
|
+
self.entrypoint = "./main.jar"
|
|
1034
|
+
else:
|
|
1035
|
+
raise ValueError(
|
|
1036
|
+
f'entrypoint is not provided but the runtime "{self.runtime}" could not '
|
|
1037
|
+
"be resolved to establish a default entrypoint"
|
|
1038
|
+
)
|
|
836
1039
|
|
|
837
1040
|
@classmethod
|
|
838
1041
|
def from_yaml(cls, dirpath: str) -> "Manifest":
|
|
@@ -871,7 +1074,7 @@ class Manifest(BaseModel):
|
|
|
871
1074
|
type: python
|
|
872
1075
|
```
|
|
873
1076
|
|
|
874
|
-
>>> from nextmv
|
|
1077
|
+
>>> from nextmv import Manifest
|
|
875
1078
|
>>> # manifest = Manifest.from_yaml("./my_app_dir") # This would be run
|
|
876
1079
|
>>> # assert manifest.type == "python"
|
|
877
1080
|
"""
|
|
@@ -902,7 +1105,7 @@ class Manifest(BaseModel):
|
|
|
902
1105
|
|
|
903
1106
|
Examples
|
|
904
1107
|
--------
|
|
905
|
-
>>> from nextmv
|
|
1108
|
+
>>> from nextmv import Manifest
|
|
906
1109
|
>>> manifest = Manifest(files=["solver.py"], type="python")
|
|
907
1110
|
>>> # manifest.to_yaml("./output_dir") # This would create ./output_dir/app.yaml
|
|
908
1111
|
"""
|
|
@@ -925,7 +1128,7 @@ class Manifest(BaseModel):
|
|
|
925
1128
|
|
|
926
1129
|
Examples
|
|
927
1130
|
--------
|
|
928
|
-
>>> from nextmv
|
|
1131
|
+
>>> from nextmv import Manifest, ManifestConfiguration, ManifestOptions, ManifestOption
|
|
929
1132
|
>>> manifest = Manifest(
|
|
930
1133
|
... files=["main.py"],
|
|
931
1134
|
... configuration=ManifestConfiguration(
|
|
@@ -987,8 +1190,9 @@ class Manifest(BaseModel):
|
|
|
987
1190
|
|
|
988
1191
|
Examples
|
|
989
1192
|
--------
|
|
990
|
-
>>> from nextmv.model import ModelConfiguration
|
|
991
|
-
>>> from nextmv.
|
|
1193
|
+
>>> from nextmv.model import ModelConfiguration
|
|
1194
|
+
>>> from nextmv.options import Options, Option
|
|
1195
|
+
>>> from nextmv import Manifest
|
|
992
1196
|
>>> opts = Options(Option(name="vehicle_count", option_type=int, default=5))
|
|
993
1197
|
>>> mc = ModelConfiguration(name="vehicle_router", options=opts)
|
|
994
1198
|
>>> manifest = Manifest.from_model_configuration(mc)
|
|
@@ -1050,7 +1254,7 @@ class Manifest(BaseModel):
|
|
|
1050
1254
|
----------
|
|
1051
1255
|
options : nextmv.options.Options
|
|
1052
1256
|
The options to include in the manifest.
|
|
1053
|
-
validation : nextmv.options.OptionsEnforcement default=None
|
|
1257
|
+
validation : nextmv.options.OptionsEnforcement, default=None
|
|
1054
1258
|
The validation rules for the options. This is used to set the
|
|
1055
1259
|
`validation` attribute of the `ManifestOptions`.
|
|
1056
1260
|
|
|
@@ -1062,7 +1266,7 @@ class Manifest(BaseModel):
|
|
|
1062
1266
|
Examples
|
|
1063
1267
|
--------
|
|
1064
1268
|
>>> from nextmv.options import Options, Option
|
|
1065
|
-
>>> from nextmv
|
|
1269
|
+
>>> from nextmv import Manifest
|
|
1066
1270
|
>>> opts = Options(
|
|
1067
1271
|
... Option(name="max_runtime", option_type=str, default="60s"),
|
|
1068
1272
|
... Option(name="use_heuristic", option_type=bool, default=True)
|