nextmv 0.35.0.dev1__tar.gz → 0.35.1__tar.gz

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 (88) hide show
  1. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/PKG-INFO +3 -4
  2. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/README.md +1 -1
  3. nextmv-0.35.1/nextmv/__about__.py +1 -0
  4. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/__init__.py +1 -0
  5. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/_serialization.py +3 -3
  6. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/base_model.py +2 -2
  7. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/cloud/acceptance_test.py +4 -5
  8. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/cloud/application.py +116 -109
  9. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/cloud/batch_experiment.py +17 -17
  10. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/cloud/client.py +13 -13
  11. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/cloud/ensemble.py +2 -3
  12. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/cloud/input_set.py +7 -8
  13. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/cloud/instance.py +3 -4
  14. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/cloud/package.py +18 -12
  15. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/cloud/scenario.py +6 -10
  16. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/default_app/README.md +2 -2
  17. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/input.py +38 -44
  18. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/local/application.py +38 -38
  19. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/local/executor.py +47 -17
  20. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/local/runner.py +10 -10
  21. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/manifest.py +69 -79
  22. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/model.py +6 -6
  23. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/options.py +12 -12
  24. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/output.py +46 -61
  25. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/polling.py +2 -2
  26. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/run.py +58 -58
  27. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/pyproject.toml +1 -2
  28. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/local/test_application.py +2 -2
  29. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/local/test_executor.py +6 -5
  30. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/local/test_runner.py +1 -2
  31. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/test_base_model.py +3 -4
  32. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/test_input.py +1 -2
  33. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/test_manifest.py +20 -1
  34. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/test_output.py +2 -2
  35. nextmv-0.35.0.dev1/nextmv/__about__.py +0 -1
  36. nextmv-0.35.0.dev1/nextmv/default_app/src/main.py +0 -37
  37. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/.gitignore +0 -0
  38. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/LICENSE +0 -0
  39. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/__entrypoint__.py +0 -0
  40. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/cloud/__init__.py +0 -0
  41. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/cloud/account.py +0 -0
  42. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/cloud/secrets.py +0 -0
  43. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/cloud/url.py +0 -0
  44. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/cloud/version.py +0 -0
  45. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/default_app/.gitignore +0 -0
  46. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/default_app/app.yaml +0 -0
  47. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/default_app/input.json +0 -0
  48. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/default_app/main.py +0 -0
  49. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/default_app/requirements.txt +0 -0
  50. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/default_app/src/__init__.py +0 -0
  51. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/default_app/src/visuals.py +0 -0
  52. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/deprecated.py +0 -0
  53. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/local/__init__.py +0 -0
  54. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/local/geojson_handler.py +0 -0
  55. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/local/local.py +0 -0
  56. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/local/plotly_handler.py +0 -0
  57. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/logger.py +0 -0
  58. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/safe.py +0 -0
  59. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/nextmv/status.py +0 -0
  60. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/__init__.py +0 -0
  61. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/cloud/__init__.py +0 -0
  62. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/cloud/app.yaml +0 -0
  63. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/cloud/test_client.py +0 -0
  64. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/cloud/test_package.py +0 -0
  65. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/cloud/test_scenario.py +0 -0
  66. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/local/__init__.py +0 -0
  67. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/scripts/__init__.py +0 -0
  68. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/scripts/options1.py +0 -0
  69. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/scripts/options2.py +0 -0
  70. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/scripts/options3.py +0 -0
  71. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/scripts/options4.py +0 -0
  72. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/scripts/options5.py +0 -0
  73. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/scripts/options6.py +0 -0
  74. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/scripts/options7.py +0 -0
  75. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/scripts/options_deprecated.py +0 -0
  76. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/test_entrypoint/__init__.py +0 -0
  77. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/test_entrypoint/test_entrypoint.py +0 -0
  78. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/test_inputs/test_data.csv +0 -0
  79. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/test_inputs/test_data.json +0 -0
  80. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/test_inputs/test_data.txt +0 -0
  81. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/test_logger.py +0 -0
  82. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/test_model.py +0 -0
  83. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/test_options.py +0 -0
  84. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/test_polling.py +0 -0
  85. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/test_run.py +0 -0
  86. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/test_safe.py +0 -0
  87. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/test_serialization.py +0 -0
  88. {nextmv-0.35.0.dev1 → nextmv-0.35.1}/tests/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nextmv
3
- Version: 0.35.0.dev1
3
+ Version: 0.35.1
4
4
  Summary: The all-purpose Python SDK for Nextmv
5
5
  Project-URL: Homepage, https://www.nextmv.io
6
6
  Project-URL: Documentation, https://nextmv-py.docs.nextmv.io/en/latest/nextmv/
@@ -213,12 +213,11 @@ 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
- Classifier: Programming Language :: Python :: 3.9
217
216
  Classifier: Programming Language :: Python :: 3.10
218
217
  Classifier: Programming Language :: Python :: 3.11
219
218
  Classifier: Programming Language :: Python :: 3.12
220
219
  Classifier: Programming Language :: Python :: 3.13
221
- Requires-Python: >=3.9
220
+ Requires-Python: >=3.10
222
221
  Requires-Dist: pydantic>=2.5.2
223
222
  Requires-Dist: pyyaml>=6.0.1
224
223
  Requires-Dist: requests>=2.31.0
@@ -270,7 +269,7 @@ Welcome to `nextmv`, the general Python SDK for the Nextmv Platform.
270
269
 
271
270
  ## Installation
272
271
 
273
- Requires Python `>=3.9`. Install using `pip`:
272
+ Requires Python `>=3.10`. Install using `pip`:
274
273
 
275
274
  ```bash
276
275
  pip install nextmv
@@ -25,7 +25,7 @@ Welcome to `nextmv`, the general Python SDK for the Nextmv Platform.
25
25
 
26
26
  ## Installation
27
27
 
28
- Requires Python `>=3.9`. Install using `pip`:
28
+ Requires Python `>=3.10`. Install using `pip`:
29
29
 
30
30
  ```bash
31
31
  pip install nextmv
@@ -0,0 +1 @@
1
+ __version__ = "v0.35.1"
@@ -19,6 +19,7 @@ from .logger import reset_stdout as reset_stdout
19
19
  from .manifest import MANIFEST_FILE_NAME as MANIFEST_FILE_NAME
20
20
  from .manifest import Manifest as Manifest
21
21
  from .manifest import ManifestBuild as ManifestBuild
22
+ from .manifest import ManifestExecution as ManifestExecution
22
23
  from .manifest import ManifestOption as ManifestOption
23
24
  from .manifest import ManifestPython as ManifestPython
24
25
  from .manifest import ManifestPythonArch as ManifestPythonArch
@@ -1,9 +1,9 @@
1
1
  import datetime
2
2
  import json
3
- from typing import Any, Union
3
+ from typing import Any
4
4
 
5
5
 
6
- def deflated_serialize_json(obj: Union[dict, list], json_configurations: dict[str, Any] = None) -> str:
6
+ def deflated_serialize_json(obj: dict | list, json_configurations: dict[str, Any] = None) -> str:
7
7
  """
8
8
  Serialize a Python object (dict or list) to a JSON string with default configuration for a deflated format.
9
9
 
@@ -35,7 +35,7 @@ def deflated_serialize_json(obj: Union[dict, list], json_configurations: dict[st
35
35
  )
36
36
 
37
37
 
38
- def serialize_json(obj: Union[dict, list], json_configurations: dict[str, Any] = None) -> str:
38
+ def serialize_json(obj: dict | list, json_configurations: dict[str, Any] = None) -> str:
39
39
  """
40
40
  Serialize a Python object (dict or list) to a JSON string.
41
41
 
@@ -18,7 +18,7 @@ from_dict:
18
18
  """
19
19
 
20
20
  from importlib import import_module
21
- from typing import Any, Optional
21
+ from typing import Any
22
22
 
23
23
  from pydantic import BaseModel as PydanticBaseModel
24
24
 
@@ -32,7 +32,7 @@ class BaseModel(PydanticBaseModel):
32
32
  """
33
33
 
34
34
  @classmethod
35
- def from_dict(cls, data: Optional[dict[str, Any]] = None):
35
+ def from_dict(cls, data: dict[str, Any] | None = None):
36
36
  """
37
37
  Instantiate the class from a dictionary.
38
38
 
@@ -43,7 +43,6 @@ AcceptanceTest : BaseModel
43
43
 
44
44
  from datetime import datetime
45
45
  from enum import Enum
46
- from typing import Optional
47
46
 
48
47
  from nextmv.base_model import BaseModel
49
48
  from nextmv.cloud.batch_experiment import ExperimentStatus
@@ -861,9 +860,9 @@ class AcceptanceTestResults(BaseModel):
861
860
 
862
861
  passed: bool
863
862
  """Whether the acceptance test passed (or not)."""
864
- metric_results: Optional[list[MetricResult]] = None
863
+ metric_results: list[MetricResult] | None = None
865
864
  """Results of the metrics."""
866
- error: Optional[str] = None
865
+ error: str | None = None
867
866
  """Error message if the acceptance test failed."""
868
867
 
869
868
 
@@ -957,7 +956,7 @@ class AcceptanceTest(BaseModel):
957
956
  """Creation date of the acceptance test."""
958
957
  updated_at: datetime
959
958
  """Last update date of the acceptance test."""
960
- status: Optional[ExperimentStatus] = ExperimentStatus.UNKNOWN
959
+ status: ExperimentStatus | None = ExperimentStatus.UNKNOWN
961
960
  """Status of the acceptance test."""
962
- results: Optional[AcceptanceTestResults] = None
961
+ results: AcceptanceTestResults | None = None
963
962
  """Results of the acceptance test."""
@@ -29,7 +29,7 @@ import tarfile
29
29
  import tempfile
30
30
  from dataclasses import dataclass
31
31
  from datetime import datetime
32
- from typing import Any, Optional, Union
32
+ from typing import Any
33
33
 
34
34
  import requests
35
35
 
@@ -148,9 +148,9 @@ class Application:
148
148
  cls,
149
149
  client: Client,
150
150
  name: str,
151
- id: Optional[str] = None,
152
- description: Optional[str] = None,
153
- is_workflow: Optional[bool] = None,
151
+ id: str | None = None,
152
+ description: str | None = None,
153
+ is_workflow: bool | None = None,
154
154
  exist_ok: bool = False,
155
155
  ) -> "Application":
156
156
  """
@@ -1063,10 +1063,10 @@ class Application:
1063
1063
  candidate_instance_id: str,
1064
1064
  baseline_instance_id: str,
1065
1065
  id: str,
1066
- metrics: list[Union[Metric, dict[str, Any]]],
1066
+ metrics: list[Metric | dict[str, Any]],
1067
1067
  name: str,
1068
- input_set_id: Optional[str] = None,
1069
- description: Optional[str] = None,
1068
+ input_set_id: str | None = None,
1069
+ description: str | None = None,
1070
1070
  ) -> AcceptanceTest:
1071
1071
  """
1072
1072
  Create a new acceptance test.
@@ -1180,10 +1180,10 @@ class Application:
1180
1180
  candidate_instance_id: str,
1181
1181
  baseline_instance_id: str,
1182
1182
  id: str,
1183
- metrics: list[Union[Metric, dict[str, Any]]],
1183
+ metrics: list[Metric | dict[str, Any]],
1184
1184
  name: str,
1185
- input_set_id: Optional[str] = None,
1186
- description: Optional[str] = None,
1185
+ input_set_id: str | None = None,
1186
+ description: str | None = None,
1187
1187
  polling_options: PollingOptions = DEFAULT_POLLING_OPTIONS,
1188
1188
  ) -> AcceptanceTest:
1189
1189
  """
@@ -1260,13 +1260,13 @@ class Application:
1260
1260
  def new_batch_experiment(
1261
1261
  self,
1262
1262
  name: str,
1263
- input_set_id: Optional[str] = None,
1264
- instance_ids: Optional[list[str]] = None,
1265
- description: Optional[str] = None,
1266
- id: Optional[str] = None,
1267
- option_sets: Optional[dict[str, dict[str, str]]] = None,
1268
- runs: Optional[list[Union[BatchExperimentRun, dict[str, Any]]]] = None,
1269
- type: Optional[str] = "batch",
1263
+ input_set_id: str | None = None,
1264
+ instance_ids: list[str] | None = None,
1265
+ description: str | None = None,
1266
+ id: str | None = None,
1267
+ option_sets: dict[str, dict[str, str]] | None = None,
1268
+ runs: list[BatchExperimentRun | dict[str, Any]] | None = None,
1269
+ type: str | None = "batch",
1270
1270
  ) -> str:
1271
1271
  """
1272
1272
  Create a new batch experiment.
@@ -1341,13 +1341,13 @@ class Application:
1341
1341
  def new_batch_experiment_with_result(
1342
1342
  self,
1343
1343
  name: str,
1344
- input_set_id: Optional[str] = None,
1345
- instance_ids: Optional[list[str]] = None,
1346
- description: Optional[str] = None,
1347
- id: Optional[str] = None,
1348
- option_sets: Optional[dict[str, dict[str, str]]] = None,
1349
- runs: Optional[list[Union[BatchExperimentRun, dict[str, Any]]]] = None,
1350
- type: Optional[str] = "batch",
1344
+ input_set_id: str | None = None,
1345
+ instance_ids: list[str] | None = None,
1346
+ description: str | None = None,
1347
+ id: str | None = None,
1348
+ option_sets: dict[str, dict[str, str]] | None = None,
1349
+ runs: list[BatchExperimentRun | dict[str, Any]] | None = None,
1350
+ type: str | None = "batch",
1351
1351
  polling_options: PollingOptions = DEFAULT_POLLING_OPTIONS,
1352
1352
  ) -> BatchExperiment:
1353
1353
  """
@@ -1413,8 +1413,8 @@ class Application:
1413
1413
  id: str,
1414
1414
  run_groups: list[RunGroup],
1415
1415
  rules: list[EvaluationRule],
1416
- name: Optional[str] = None,
1417
- description: Optional[str] = None,
1416
+ name: str | None = None,
1417
+ description: str | None = None,
1418
1418
  ) -> EnsembleDefinition:
1419
1419
  """
1420
1420
  Create a new ensemble definition.
@@ -1459,13 +1459,13 @@ class Application:
1459
1459
  self,
1460
1460
  id: str,
1461
1461
  name: str,
1462
- description: Optional[str] = None,
1463
- end_time: Optional[datetime] = None,
1464
- instance_id: Optional[str] = None,
1465
- maximum_runs: Optional[int] = None,
1466
- run_ids: Optional[list[str]] = None,
1467
- start_time: Optional[datetime] = None,
1468
- inputs: Optional[list[ManagedInput]] = None,
1462
+ description: str | None = None,
1463
+ end_time: datetime | None = None,
1464
+ instance_id: str | None = None,
1465
+ maximum_runs: int | None = None,
1466
+ run_ids: list[str] | None = None,
1467
+ start_time: datetime | None = None,
1468
+ inputs: list[ManagedInput] | None = None,
1469
1469
  ) -> InputSet:
1470
1470
  """
1471
1471
  Create a new input set. You can create an input set from three
@@ -1553,8 +1553,8 @@ class Application:
1553
1553
  version_id: str,
1554
1554
  id: str,
1555
1555
  name: str,
1556
- description: Optional[str] = None,
1557
- configuration: Optional[InstanceConfiguration] = None,
1556
+ description: str | None = None,
1557
+ configuration: InstanceConfiguration | None = None,
1558
1558
  exist_ok: bool = False,
1559
1559
  ) -> Instance:
1560
1560
  """
@@ -1636,10 +1636,10 @@ class Application:
1636
1636
  self,
1637
1637
  id: str,
1638
1638
  name: str,
1639
- description: Optional[str] = None,
1640
- upload_id: Optional[str] = None,
1641
- run_id: Optional[str] = None,
1642
- format: Optional[Union[Format, dict[str, Any]]] = None,
1639
+ description: str | None = None,
1640
+ upload_id: str | None = None,
1641
+ run_id: str | None = None,
1642
+ format: Format | dict[str, Any] | None = None,
1643
1643
  ) -> ManagedInput:
1644
1644
  """
1645
1645
  Create a new managed input. There are two methods for creating a
@@ -1715,17 +1715,17 @@ class Application:
1715
1715
 
1716
1716
  def new_run( # noqa: C901 # Refactor this function at some point.
1717
1717
  self,
1718
- input: Union[Input, dict[str, Any], BaseModel, str] = None,
1719
- instance_id: Optional[str] = None,
1720
- name: Optional[str] = None,
1721
- description: Optional[str] = None,
1722
- upload_id: Optional[str] = None,
1723
- options: Optional[Union[Options, dict[str, str]]] = None,
1724
- configuration: Optional[Union[RunConfiguration, dict[str, Any]]] = None,
1725
- batch_experiment_id: Optional[str] = None,
1726
- external_result: Optional[Union[ExternalRunResult, dict[str, Any]]] = None,
1727
- json_configurations: Optional[dict[str, Any]] = None,
1728
- input_dir_path: Optional[str] = None,
1718
+ input: Input | dict[str, Any] | BaseModel | str = None,
1719
+ instance_id: str | None = None,
1720
+ name: str | None = None,
1721
+ description: str | None = None,
1722
+ upload_id: str | None = None,
1723
+ options: Options | dict[str, str] | None = None,
1724
+ configuration: RunConfiguration | dict[str, Any] | None = None,
1725
+ batch_experiment_id: str | None = None,
1726
+ external_result: ExternalRunResult | dict[str, Any] | None = None,
1727
+ json_configurations: dict[str, Any] | None = None,
1728
+ input_dir_path: str | None = None,
1729
1729
  ) -> str:
1730
1730
  """
1731
1731
  Submit an input to start a new run of the application. Returns the
@@ -1893,19 +1893,19 @@ class Application:
1893
1893
 
1894
1894
  def new_run_with_result(
1895
1895
  self,
1896
- input: Union[Input, dict[str, Any], BaseModel, str] = None,
1897
- instance_id: Optional[str] = None,
1898
- name: Optional[str] = None,
1899
- description: Optional[str] = None,
1900
- upload_id: Optional[str] = None,
1901
- run_options: Optional[Union[Options, dict[str, str]]] = None,
1896
+ input: Input | dict[str, Any] | BaseModel | str = None,
1897
+ instance_id: str | None = None,
1898
+ name: str | None = None,
1899
+ description: str | None = None,
1900
+ upload_id: str | None = None,
1901
+ run_options: Options | dict[str, str] | None = None,
1902
1902
  polling_options: PollingOptions = DEFAULT_POLLING_OPTIONS,
1903
- configuration: Optional[Union[RunConfiguration, dict[str, Any]]] = None,
1904
- batch_experiment_id: Optional[str] = None,
1905
- external_result: Optional[Union[ExternalRunResult, dict[str, Any]]] = None,
1906
- json_configurations: Optional[dict[str, Any]] = None,
1907
- input_dir_path: Optional[str] = None,
1908
- output_dir_path: Optional[str] = ".",
1903
+ configuration: RunConfiguration | dict[str, Any] | None = None,
1904
+ batch_experiment_id: str | None = None,
1905
+ external_result: ExternalRunResult | dict[str, Any] | None = None,
1906
+ json_configurations: dict[str, Any] | None = None,
1907
+ input_dir_path: str | None = None,
1908
+ output_dir_path: str | None = ".",
1909
1909
  ) -> RunResult:
1910
1910
  """
1911
1911
  Submit an input to start a new run of the application and poll for the
@@ -2045,8 +2045,8 @@ class Application:
2045
2045
  id: str,
2046
2046
  name: str,
2047
2047
  scenarios: list[Scenario],
2048
- description: Optional[str] = None,
2049
- repetitions: Optional[int] = 0,
2048
+ description: str | None = None,
2049
+ repetitions: int | None = 0,
2050
2050
  ) -> str:
2051
2051
  """
2052
2052
  Create a new scenario test. The test is based on `scenarios` and you
@@ -2166,8 +2166,8 @@ class Application:
2166
2166
  id: str,
2167
2167
  name: str,
2168
2168
  scenarios: list[Scenario],
2169
- description: Optional[str] = None,
2170
- repetitions: Optional[int] = 0,
2169
+ description: str | None = None,
2170
+ repetitions: int | None = 0,
2171
2171
  polling_options: PollingOptions = DEFAULT_POLLING_OPTIONS,
2172
2172
  ) -> BatchExperiment:
2173
2173
  """
@@ -2229,7 +2229,7 @@ class Application:
2229
2229
  secrets: list[Secret],
2230
2230
  id: str,
2231
2231
  name: str,
2232
- description: Optional[str] = None,
2232
+ description: str | None = None,
2233
2233
  ) -> SecretsCollectionSummary:
2234
2234
  """
2235
2235
  Create a new secrets collection.
@@ -2313,9 +2313,9 @@ class Application:
2313
2313
 
2314
2314
  def new_version(
2315
2315
  self,
2316
- id: Optional[str] = None,
2317
- name: Optional[str] = None,
2318
- description: Optional[str] = None,
2316
+ id: str | None = None,
2317
+ name: str | None = None,
2318
+ description: str | None = None,
2319
2319
  exist_ok: bool = False,
2320
2320
  ) -> Version:
2321
2321
  """
@@ -2397,11 +2397,11 @@ class Application:
2397
2397
 
2398
2398
  def push(
2399
2399
  self,
2400
- manifest: Optional[Manifest] = None,
2401
- app_dir: Optional[str] = None,
2400
+ manifest: Manifest | None = None,
2401
+ app_dir: str | None = None,
2402
2402
  verbose: bool = False,
2403
- model: Optional[Model] = None,
2404
- model_configuration: Optional[ModelConfiguration] = None,
2403
+ model: Model | None = None,
2404
+ model_configuration: ModelConfiguration | None = None,
2405
2405
  ) -> None:
2406
2406
  """
2407
2407
  Push an app to Nextmv Cloud.
@@ -2664,7 +2664,7 @@ class Application:
2664
2664
  )
2665
2665
  return RunLog.from_dict(response.json())
2666
2666
 
2667
- def run_result(self, run_id: str, output_dir_path: Optional[str] = ".") -> RunResult:
2667
+ def run_result(self, run_id: str, output_dir_path: str | None = ".") -> RunResult:
2668
2668
  """
2669
2669
  Get the result of a run.
2670
2670
 
@@ -2708,7 +2708,7 @@ class Application:
2708
2708
  self,
2709
2709
  run_id: str,
2710
2710
  polling_options: PollingOptions = DEFAULT_POLLING_OPTIONS,
2711
- output_dir_path: Optional[str] = ".",
2711
+ output_dir_path: str | None = ".",
2712
2712
  ) -> RunResult:
2713
2713
  """
2714
2714
  Get the result of a run with polling.
@@ -2887,8 +2887,8 @@ class Application:
2887
2887
  def track_run( # noqa: C901
2888
2888
  self,
2889
2889
  tracked_run: TrackedRun,
2890
- instance_id: Optional[str] = None,
2891
- configuration: Optional[Union[RunConfiguration, dict[str, Any]]] = None,
2890
+ instance_id: str | None = None,
2891
+ configuration: RunConfiguration | dict[str, Any] | None = None,
2892
2892
  ) -> str:
2893
2893
  """
2894
2894
  Track an external run.
@@ -3058,9 +3058,9 @@ class Application:
3058
3058
  self,
3059
3059
  tracked_run: TrackedRun,
3060
3060
  polling_options: PollingOptions = DEFAULT_POLLING_OPTIONS,
3061
- instance_id: Optional[str] = None,
3062
- output_dir_path: Optional[str] = ".",
3063
- configuration: Optional[Union[RunConfiguration, dict[str, Any]]] = None,
3061
+ instance_id: str | None = None,
3062
+ output_dir_path: str | None = ".",
3063
+ configuration: RunConfiguration | dict[str, Any] | None = None,
3064
3064
  ) -> RunResult:
3065
3065
  """
3066
3066
  Track an external run and poll for the result. This is a convenience
@@ -3120,8 +3120,8 @@ class Application:
3120
3120
  def update_batch_experiment(
3121
3121
  self,
3122
3122
  batch_experiment_id: str,
3123
- name: Optional[str] = None,
3124
- description: Optional[str] = None,
3123
+ name: str | None = None,
3124
+ description: str | None = None,
3125
3125
  ) -> BatchExperimentInformation:
3126
3126
  """
3127
3127
  Update a batch experiment.
@@ -3164,8 +3164,8 @@ class Application:
3164
3164
  def update_ensemble_definition(
3165
3165
  self,
3166
3166
  id: str,
3167
- name: Optional[str] = None,
3168
- description: Optional[str] = None,
3167
+ name: str | None = None,
3168
+ description: str | None = None,
3169
3169
  ) -> EnsembleDefinition:
3170
3170
  """
3171
3171
  Update an ensemble definition.
@@ -3212,10 +3212,10 @@ class Application:
3212
3212
  def update_instance(
3213
3213
  self,
3214
3214
  id: str,
3215
- name: Optional[str] = None,
3216
- version_id: Optional[str] = None,
3217
- description: Optional[str] = None,
3218
- configuration: Optional[InstanceConfiguration] = None,
3215
+ name: str | None = None,
3216
+ version_id: str | None = None,
3217
+ description: str | None = None,
3218
+ configuration: InstanceConfiguration | None = None,
3219
3219
  ) -> Instance:
3220
3220
  """
3221
3221
  Update an instance.
@@ -3275,8 +3275,8 @@ class Application:
3275
3275
  def update_managed_input(
3276
3276
  self,
3277
3277
  managed_input_id: str,
3278
- name: Optional[str] = None,
3279
- description: Optional[str] = None,
3278
+ name: str | None = None,
3279
+ description: str | None = None,
3280
3280
  ) -> ManagedInput:
3281
3281
  """
3282
3282
  Update a managed input.
@@ -3325,8 +3325,8 @@ class Application:
3325
3325
  def update_scenario_test(
3326
3326
  self,
3327
3327
  scenario_test_id: str,
3328
- name: Optional[str] = None,
3329
- description: Optional[str] = None,
3328
+ name: str | None = None,
3329
+ description: str | None = None,
3330
3330
  ) -> BatchExperimentInformation:
3331
3331
  """
3332
3332
  Update a scenario test.
@@ -3374,9 +3374,9 @@ class Application:
3374
3374
  def update_secrets_collection(
3375
3375
  self,
3376
3376
  secrets_collection_id: str,
3377
- name: Optional[str] = None,
3378
- description: Optional[str] = None,
3379
- secrets: Optional[list[Secret]] = None,
3377
+ name: str | None = None,
3378
+ description: str | None = None,
3379
+ secrets: list[Secret] | None = None,
3380
3380
  ) -> SecretsCollectionSummary:
3381
3381
  """
3382
3382
  Update a secrets collection.
@@ -3453,10 +3453,10 @@ class Application:
3453
3453
 
3454
3454
  def upload_large_input(
3455
3455
  self,
3456
- input: Optional[Union[dict[str, Any], str]],
3456
+ input: dict[str, Any] | str | None,
3457
3457
  upload_url: UploadURL,
3458
- json_configurations: Optional[dict[str, Any]] = None,
3459
- tar_file: Optional[str] = None,
3458
+ json_configurations: dict[str, Any] | None = None,
3459
+ tar_file: str | None = None,
3460
3460
  ) -> None:
3461
3461
  """
3462
3462
  Upload large input data to the provided upload URL.
@@ -3676,7 +3676,7 @@ class Application:
3676
3676
  self,
3677
3677
  run_id: str,
3678
3678
  run_information: RunInformation,
3679
- output_dir_path: Optional[str] = ".",
3679
+ output_dir_path: str | None = ".",
3680
3680
  ) -> RunResult:
3681
3681
  """
3682
3682
  Get the result of a run.
@@ -3764,7 +3764,7 @@ class Application:
3764
3764
  return result
3765
3765
 
3766
3766
  @staticmethod
3767
- def __convert_manifest_to_payload(manifest: Manifest) -> dict[str, Any]:
3767
+ def __convert_manifest_to_payload(manifest: Manifest) -> dict[str, Any]: # noqa: C901
3768
3768
  """Converts a manifest to a payload dictionary for the API."""
3769
3769
 
3770
3770
  activation_request = {
@@ -3802,6 +3802,13 @@ class Application:
3802
3802
  "template": options["format"],
3803
3803
  }
3804
3804
  activation_request["requirements"]["options"] = options
3805
+
3806
+ if manifest.execution is not None:
3807
+ if manifest.execution.entrypoint:
3808
+ activation_request["requirements"]["entrypoint"] = manifest.execution.entrypoint
3809
+ if manifest.execution.cwd:
3810
+ activation_request["requirements"]["working_directory"] = manifest.execution.cwd
3811
+
3805
3812
  return activation_request
3806
3813
 
3807
3814
  def __update_app_binary(
@@ -3943,7 +3950,7 @@ class Application:
3943
3950
  upload_id_used: bool,
3944
3951
  input_size: int,
3945
3952
  tar_file: str,
3946
- input: Union[Input, dict[str, Any], BaseModel, str] = None,
3953
+ input: Input | dict[str, Any] | BaseModel | str = None,
3947
3954
  ) -> bool:
3948
3955
  """
3949
3956
  Auxiliary function to determine if an upload URL is required
@@ -3967,8 +3974,8 @@ class Application:
3967
3974
 
3968
3975
  def __extract_input_data(
3969
3976
  self,
3970
- input: Union[Input, dict[str, Any], BaseModel, str] = None,
3971
- ) -> Optional[Union[dict[str, Any], str]]:
3977
+ input: Input | dict[str, Any] | BaseModel | str = None,
3978
+ ) -> dict[str, Any] | str | None:
3972
3979
  """
3973
3980
  Auxiliary function to extract the input data from the input, based on
3974
3981
  its type.
@@ -3986,8 +3993,8 @@ class Application:
3986
3993
 
3987
3994
  def __extract_options_dict(
3988
3995
  self,
3989
- options: Optional[Union[Options, dict[str, str]]] = None,
3990
- json_configurations: Optional[dict[str, Any]] = None,
3996
+ options: Options | dict[str, str] | None = None,
3997
+ json_configurations: dict[str, Any] | None = None,
3991
3998
  ) -> dict[str, str]:
3992
3999
  """
3993
4000
  Auxiliary function to extract the options that will be sent to the
@@ -4011,9 +4018,9 @@ class Application:
4011
4018
 
4012
4019
  def __extract_run_config(
4013
4020
  self,
4014
- input: Union[Input, dict[str, Any], BaseModel, str] = None,
4015
- configuration: Optional[Union[RunConfiguration, dict[str, Any]]] = None,
4016
- dir_path: Optional[str] = None,
4021
+ input: Input | dict[str, Any] | BaseModel | str = None,
4022
+ configuration: RunConfiguration | dict[str, Any] | None = None,
4023
+ dir_path: str | None = None,
4017
4024
  ) -> dict[str, Any]:
4018
4025
  """
4019
4026
  Auxiliary function to extract the run configuration that will be sent