nextmv 0.35.0__py3-none-any.whl → 0.35.0.dev1__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/output.py CHANGED
@@ -60,7 +60,7 @@ import sys
60
60
  from collections.abc import Callable
61
61
  from dataclasses import dataclass
62
62
  from enum import Enum
63
- from typing import Any
63
+ from typing import Any, Optional, Union
64
64
 
65
65
  from pydantic import AliasChoices, Field
66
66
 
@@ -119,11 +119,16 @@ class RunStatistics(BaseModel):
119
119
  {'duration': 10.5, 'iterations': 100, 'custom': {'convergence': 0.001}}
120
120
  """
121
121
 
122
- duration: float | None = None
122
+ duration: Optional[float] = None
123
123
  """Duration of the run in seconds."""
124
- iterations: int | None = None
124
+ iterations: Optional[int] = None
125
125
  """Number of iterations."""
126
- custom: Any | dict[str, Any] | None = None
126
+ custom: Optional[
127
+ Union[
128
+ Any,
129
+ dict[str, Any],
130
+ ]
131
+ ] = None
127
132
  """Custom statistics created by the user. Can normally expect a `dict[str,
128
133
  Any]`."""
129
134
 
@@ -159,11 +164,16 @@ class ResultStatistics(BaseModel):
159
164
  {'duration': 5.2, 'value': 42.0, 'custom': {'gap': 0.05}}
160
165
  """
161
166
 
162
- duration: float | None = None
167
+ duration: Optional[float] = None
163
168
  """Duration of the run in seconds."""
164
- value: float | None = None
169
+ value: Optional[float] = None
165
170
  """Value of the result."""
166
- custom: Any | dict[str, Any] | None = None
171
+ custom: Optional[
172
+ Union[
173
+ Any,
174
+ dict[str, Any],
175
+ ]
176
+ ] = None
167
177
  """Custom statistics created by the user. Can normally expect a `dict[str,
168
178
  Any]`."""
169
179
 
@@ -229,9 +239,9 @@ class Series(BaseModel):
229
239
  2
230
240
  """
231
241
 
232
- name: str | None = None
242
+ name: Optional[str] = None
233
243
  """Name of the series."""
234
- data_points: list[DataPoint] | None = None
244
+ data_points: Optional[list[DataPoint]] = None
235
245
  """Data of the series."""
236
246
 
237
247
 
@@ -264,9 +274,9 @@ class SeriesData(BaseModel):
264
274
  1
265
275
  """
266
276
 
267
- value: Series | None = None
277
+ value: Optional[Series] = None
268
278
  """A series for the value of the solution."""
269
- custom: list[Series] | None = None
279
+ custom: Optional[list[Series]] = None
270
280
  """A list of series for custom statistics."""
271
281
 
272
282
 
@@ -304,13 +314,13 @@ class Statistics(BaseModel):
304
314
  100.0
305
315
  """
306
316
 
307
- run: RunStatistics | None = None
317
+ run: Optional[RunStatistics] = None
308
318
  """Statistics about the run."""
309
- result: ResultStatistics | None = None
319
+ result: Optional[ResultStatistics] = None
310
320
  """Statistics about the last result."""
311
- series_data: SeriesData | None = None
321
+ series_data: Optional[SeriesData] = None
312
322
  """Data of the series."""
313
- statistics_schema: str | None = Field(
323
+ statistics_schema: Optional[str] = Field(
314
324
  serialization_alias="schema",
315
325
  validation_alias=AliasChoices("schema", "statistics_schema"),
316
326
  default="v1",
@@ -397,7 +407,7 @@ class Visual(BaseModel):
397
407
  label: str
398
408
  """Label for the custom tab of the visual asset in the Nextmv Console."""
399
409
 
400
- visual_type: str | None = Field(
410
+ visual_type: Optional[str] = Field(
401
411
  serialization_alias="type",
402
412
  validation_alias=AliasChoices("type", "visual_type"),
403
413
  default="custom-tab",
@@ -472,11 +482,11 @@ class Asset(BaseModel):
472
482
  content: Any
473
483
  """Content of the asset. The type must be serializable to JSON."""
474
484
 
475
- content_type: str | None = "json"
485
+ content_type: Optional[str] = "json"
476
486
  """Content type of the asset. Only `json` is allowed"""
477
- description: str | None = None
487
+ description: Optional[str] = None
478
488
  """Description of the asset."""
479
- visual: Visual | None = None
489
+ visual: Optional[Visual] = None
480
490
  """Visual schema of the asset."""
481
491
 
482
492
  def __post_init__(self):
@@ -623,12 +633,12 @@ class SolutionFile:
623
633
  The `writer_args` and `writer_kwargs` parameters of this class can be used
624
634
  to provide those additional arguments.
625
635
  """
626
- writer_args: list[Any] | None = None
636
+ writer_args: Optional[list[Any]] = None
627
637
  """
628
638
  Optional positional arguments to pass to the writer function. This can be
629
639
  used to customize the behavior of the writer.
630
640
  """
631
- writer_kwargs: dict[str, Any] | None = None
641
+ writer_kwargs: Optional[dict[str, Any]] = None
632
642
  """
633
643
  Optional keyword arguments to pass to the writer function. This can be used
634
644
  to customize the behavior of the writer.
@@ -638,7 +648,7 @@ class SolutionFile:
638
648
  def json_solution_file(
639
649
  name: str,
640
650
  data: dict[str, Any],
641
- json_configurations: dict[str, Any] | None = None,
651
+ json_configurations: Optional[dict[str, Any]] = None,
642
652
  ) -> SolutionFile:
643
653
  """
644
654
  This is a convenience function to build a `SolutionFile`. It writes the
@@ -701,7 +711,7 @@ def json_solution_file(
701
711
  def csv_solution_file(
702
712
  name: str,
703
713
  data: list[dict[str, Any]],
704
- csv_configurations: dict[str, Any] | None = None,
714
+ csv_configurations: Optional[dict[str, Any]] = None,
705
715
  ) -> SolutionFile:
706
716
  """
707
717
  This is a convenience function to build a `SolutionFile`. It writes the
@@ -923,7 +933,7 @@ class Output:
923
933
  True
924
934
  """
925
935
 
926
- options: Options | dict[str, Any] | None = None
936
+ options: Optional[Union[Options, dict[str, Any]]] = None
927
937
  """
928
938
  Options that the `Output` was created with. These options can be of type
929
939
  `Options` or a simple dictionary. If the options are of type `Options`,
@@ -939,13 +949,18 @@ class Output:
939
949
  }
940
950
  ```
941
951
  """
942
- output_format: OutputFormat | None = OutputFormat.JSON
952
+ output_format: Optional[OutputFormat] = OutputFormat.JSON
943
953
  """
944
954
  Format of the output data. Default is `OutputFormat.JSON`. When set to
945
955
  `OutputFormat.MULTI_FILE`, the `solution_files` field must be specified and
946
956
  cannot be `None`.
947
957
  """
948
- solution: dict[str, Any] | Any | dict[str, list[dict[str, Any]]] | None = None
958
+ solution: Optional[
959
+ Union[
960
+ Union[dict[str, Any], Any], # JSON
961
+ dict[str, list[dict[str, Any]]], # CSV_ARCHIVE
962
+ ]
963
+ ] = None
949
964
  """
950
965
  The solution to the decision problem. Use this filed when working with
951
966
  `output_format` of types:
@@ -960,7 +975,7 @@ class Output:
960
975
  this `solution` field is ignored, as you should use the `solution_files`
961
976
  field instead.
962
977
  """
963
- statistics: Statistics | dict[str, Any] | None = None
978
+ statistics: Optional[Union[Statistics, dict[str, Any]]] = None
964
979
  """
965
980
  Statistics of the solution. These statistics can be of type `Statistics` or a
966
981
  simple dictionary. If the statistics are of type `Statistics`, they will be
@@ -968,19 +983,19 @@ class Output:
968
983
  dictionary, they will be used as is. If the statistics are not provided, an
969
984
  empty dictionary will be used.
970
985
  """
971
- csv_configurations: dict[str, Any] | None = None
986
+ csv_configurations: Optional[dict[str, Any]] = None
972
987
  """
973
988
  Optional configuration for writing CSV files, to be used when the
974
989
  `output_format` is `OutputFormat.CSV_ARCHIVE`. These configurations are
975
990
  passed as kwargs to the `DictWriter` class from the `csv` module.
976
991
  """
977
- json_configurations: dict[str, Any] | None = None
992
+ json_configurations: Optional[dict[str, Any]] = None
978
993
  """
979
994
  Optional configuration for writing JSON files, to be used when the
980
995
  `output_format` is `OutputFormat.JSON`. These configurations are passed as
981
996
  kwargs to the `json.dumps` function.
982
997
  """
983
- assets: list[Asset | dict[str, Any]] | None = None
998
+ assets: Optional[list[Union[Asset, dict[str, Any]]]] = None
984
999
  """
985
1000
  Optional list of assets to be included in the output. These assets can be of
986
1001
  type `Asset` or a simple dictionary. If the assets are of type `Asset`, they
@@ -988,7 +1003,7 @@ class Output:
988
1003
  dictionary, they will be used as is. If the assets are not provided, an
989
1004
  empty list will be used.
990
1005
  """
991
- solution_files: list[SolutionFile] | None = None
1006
+ solution_files: Optional[list[SolutionFile]] = None
992
1007
  """
993
1008
  Optional list of solution files to be included in the output. These files
994
1009
  are of type `SolutionFile`, which allows for custom serialization and
@@ -1147,7 +1162,7 @@ class OutputWriter:
1147
1162
  ... print(f"Writing output to {path}")
1148
1163
  """
1149
1164
 
1150
- def write(self, output: Output | dict[str, Any] | BaseModel, *args, **kwargs) -> None:
1165
+ def write(self, output: Union[Output, dict[str, Any], BaseModel], *args, **kwargs) -> None:
1151
1166
  """
1152
1167
  Write the output data.
1153
1168
 
@@ -1197,9 +1212,9 @@ class LocalOutputWriter(OutputWriter):
1197
1212
 
1198
1213
  def _write_json(
1199
1214
  self,
1200
- output: Output | dict[str, Any] | BaseModel,
1215
+ output: Union[Output, dict[str, Any], BaseModel],
1201
1216
  output_dict: dict[str, Any],
1202
- path: str | None = None,
1217
+ path: Optional[str] = None,
1203
1218
  ) -> None:
1204
1219
  """
1205
1220
  Write output in JSON format.
@@ -1231,9 +1246,9 @@ class LocalOutputWriter(OutputWriter):
1231
1246
 
1232
1247
  def _write_archive(
1233
1248
  self,
1234
- output: Output | dict[str, Any] | BaseModel,
1249
+ output: Union[Output, dict[str, Any], BaseModel],
1235
1250
  output_dict: dict[str, Any],
1236
- path: str | None = None,
1251
+ path: Optional[str] = None,
1237
1252
  ) -> None:
1238
1253
  """
1239
1254
  Write output in CSV archive format.
@@ -1297,9 +1312,9 @@ class LocalOutputWriter(OutputWriter):
1297
1312
 
1298
1313
  def _write_multi_file(
1299
1314
  self,
1300
- output: Output | dict[str, Any] | BaseModel,
1315
+ output: Union[Output, dict[str, Any], BaseModel],
1301
1316
  output_dict: dict[str, Any],
1302
- path: str | None = None,
1317
+ path: Optional[str] = None,
1303
1318
  ) -> None:
1304
1319
  """
1305
1320
  Write output to multiple files.
@@ -1352,7 +1367,7 @@ class LocalOutputWriter(OutputWriter):
1352
1367
  parent_dir: str,
1353
1368
  output_dict: dict[str, Any],
1354
1369
  element_key: str,
1355
- json_configurations: dict[str, Any] | None = None,
1370
+ json_configurations: Optional[dict[str, Any]] = None,
1356
1371
  ):
1357
1372
  """
1358
1373
  Auxiliary function to write a specific element of the output
@@ -1425,8 +1440,8 @@ class LocalOutputWriter(OutputWriter):
1425
1440
 
1426
1441
  def write(
1427
1442
  self,
1428
- output: Output | dict[str, Any] | BaseModel,
1429
- path: str | None = None,
1443
+ output: Union[Output, dict[str, Any], BaseModel],
1444
+ path: Optional[str] = None,
1430
1445
  skip_stdout_reset: bool = False,
1431
1446
  ) -> None:
1432
1447
  """
@@ -1511,8 +1526,8 @@ class LocalOutputWriter(OutputWriter):
1511
1526
 
1512
1527
 
1513
1528
  def write_local(
1514
- output: Output | dict[str, Any],
1515
- path: str | None = None,
1529
+ output: Union[Output, dict[str, Any]],
1530
+ path: Optional[str] = None,
1516
1531
  skip_stdout_reset: bool = False,
1517
1532
  ) -> None:
1518
1533
  """
@@ -1576,10 +1591,10 @@ _LOCAL_OUTPUT_WRITER = LocalOutputWriter()
1576
1591
 
1577
1592
 
1578
1593
  def write(
1579
- output: Output | dict[str, Any] | BaseModel,
1580
- path: str | None = None,
1594
+ output: Union[Output, dict[str, Any], BaseModel],
1595
+ path: Optional[str] = None,
1581
1596
  skip_stdout_reset: bool = False,
1582
- writer: OutputWriter | None = _LOCAL_OUTPUT_WRITER,
1597
+ writer: Optional[OutputWriter] = _LOCAL_OUTPUT_WRITER,
1583
1598
  ) -> None:
1584
1599
  """
1585
1600
  Write the output to the specified destination.
nextmv/polling.py CHANGED
@@ -19,7 +19,7 @@ import random
19
19
  import time
20
20
  from collections.abc import Callable
21
21
  from dataclasses import dataclass
22
- from typing import Any
22
+ from typing import Any, Optional
23
23
 
24
24
  from nextmv.logger import log
25
25
 
@@ -121,7 +121,7 @@ class PollingOptions:
121
121
  """
122
122
  verbose: bool = False
123
123
  """Whether to log the polling strategy. This is useful for debugging."""
124
- stop: Callable[[], bool] | None = None
124
+ stop: Optional[Callable[[], bool]] = None
125
125
  """
126
126
  Function to call to check if the polling should stop. This is useful for
127
127
  stopping the polling based on external conditions. The function should
nextmv/run.py CHANGED
@@ -45,7 +45,7 @@ run_duration(start, end)
45
45
  from dataclasses import dataclass
46
46
  from datetime import datetime
47
47
  from enum import Enum
48
- from typing import Any
48
+ from typing import Any, Optional, Union
49
49
 
50
50
  from pydantic import AliasChoices, Field, field_validator
51
51
 
@@ -56,7 +56,7 @@ from nextmv.output import Asset, Output, OutputFormat, Statistics
56
56
  from nextmv.status import Status, StatusV2
57
57
 
58
58
 
59
- def run_duration(start: datetime | float, end: datetime | float) -> int:
59
+ def run_duration(start: Union[datetime, float], end: Union[datetime, float]) -> int:
60
60
  """
61
61
  Calculate the duration of a run in milliseconds.
62
62
 
@@ -218,7 +218,7 @@ class Format(BaseModel):
218
218
  validation_alias=AliasChoices("input", "format_input"),
219
219
  )
220
220
  """Input format for the run configuration."""
221
- format_output: FormatOutput | None = Field(
221
+ format_output: Optional[FormatOutput] = Field(
222
222
  serialization_alias="output",
223
223
  validation_alias=AliasChoices("output", "format_output"),
224
224
  default=None,
@@ -322,15 +322,15 @@ class RunTypeConfiguration(BaseModel):
322
322
  'def-67890'
323
323
  """
324
324
 
325
- run_type: RunType | None = Field(
325
+ run_type: Optional[RunType] = Field(
326
326
  serialization_alias="type",
327
327
  validation_alias=AliasChoices("type", "run_type"),
328
328
  default=None,
329
329
  )
330
330
  """Type of the run."""
331
- definition_id: str | None = None
331
+ definition_id: Optional[str] = None
332
332
  """ID of the definition for the run type."""
333
- reference_id: str | None = None
333
+ reference_id: Optional[str] = None
334
334
  """ID of the reference for the run type."""
335
335
 
336
336
  @field_validator("run_type", mode="before")
@@ -428,9 +428,9 @@ class RunInfoStatistics(BaseModel):
428
428
  status: str
429
429
  """Status of the statistics in the run."""
430
430
 
431
- error: str | None = None
431
+ error: Optional[str] = None
432
432
  """Error message if the statistics could not be retrieved."""
433
- indicators: list[StatisticsIndicator] | None = None
433
+ indicators: Optional[list[StatisticsIndicator]] = None
434
434
  """List of statistics indicators."""
435
435
 
436
436
 
@@ -598,31 +598,31 @@ class Run(BaseModel):
598
598
  status_v2: StatusV2
599
599
  """Status of the run."""
600
600
 
601
- status: Status | None = None
601
+ status: Optional[Status] = None
602
602
  """Deprecated, use status_v2 instead."""
603
- queuing_priority: int | None = None
603
+ queuing_priority: Optional[int] = None
604
604
  """Priority of the run in the queue."""
605
- queuing_disabled: bool | None = None
605
+ queuing_disabled: Optional[bool] = None
606
606
  """Whether the run is disabled from queuing."""
607
- experiment_id: str | None = None
607
+ experiment_id: Optional[str] = None
608
608
  """ID of the experiment associated with the run."""
609
- statistics: RunInfoStatistics | None = None
609
+ statistics: Optional[RunInfoStatistics] = None
610
610
  """Statistics of the run."""
611
- input_id: str | None = None
611
+ input_id: Optional[str] = None
612
612
  """ID of the input associated with the run."""
613
- option_set: str | None = None
613
+ option_set: Optional[str] = None
614
614
  """ID of the option set associated with the run."""
615
- options: dict[str, str] | None = None
615
+ options: Optional[dict[str, str]] = None
616
616
  """Options associated with the run."""
617
- request_options: dict[str, str] | None = None
617
+ request_options: Optional[dict[str, str]] = None
618
618
  """Request options associated with the run."""
619
- options_summary: list[OptionsSummaryItem] | None = None
619
+ options_summary: Optional[list[OptionsSummaryItem]] = None
620
620
  """Summary of options used in the run."""
621
- scenario_id: str | None = None
621
+ scenario_id: Optional[str] = None
622
622
  """ID of the scenario associated with the run."""
623
- repetition: int | None = None
623
+ repetition: Optional[int] = None
624
624
  """Repetition number of the run."""
625
- input_set_id: str | None = None
625
+ input_set_id: Optional[str] = None
626
626
  """ID of the input set associated with the run."""
627
627
 
628
628
 
@@ -682,9 +682,9 @@ class Metadata(BaseModel):
682
682
  """Format of the input and output of the run."""
683
683
  status_v2: StatusV2
684
684
  """Status of the run."""
685
- status: Status | None = None
685
+ status: Optional[Status] = None
686
686
  """Deprecated: use status_v2."""
687
- statistics: dict[str, Any] | None = None
687
+ statistics: Optional[dict[str, Any]] = None
688
688
  """User defined statistics of the run."""
689
689
 
690
690
 
@@ -730,7 +730,7 @@ class SyncedRun(BaseModel):
730
730
  The ID of the remote application that the local run was synced to.
731
731
  """
732
732
 
733
- instance_id: str | None = None
733
+ instance_id: Optional[str] = None
734
734
  """
735
735
  The instance of the remote application that the local run was synced to.
736
736
  This field is optional and may be None. If it is not specified, it
@@ -778,7 +778,7 @@ class RunInformation(BaseModel):
778
778
  """
779
779
  URL to the run in the Nextmv console.
780
780
  """
781
- synced_runs: list[SyncedRun] | None = None
781
+ synced_runs: Optional[list[SyncedRun]] = None
782
782
  """
783
783
  List of synced runs associated with this run, if applicable. When the
784
784
  `Application.sync` method is used, this field contains the associations
@@ -907,7 +907,7 @@ class RunInformation(BaseModel):
907
907
 
908
908
  return True
909
909
 
910
- def is_synced(self, app_id: str, instance_id: str | None = None) -> tuple[SyncedRun, bool]:
910
+ def is_synced(self, app_id: str, instance_id: Optional[str] = None) -> tuple[SyncedRun, bool]:
911
911
  """
912
912
  Check if the run has been synced to a specific application and instance.
913
913
 
@@ -965,11 +965,11 @@ class ErrorLog(BaseModel):
965
965
  Standard error. Defaults to None.
966
966
  """
967
967
 
968
- error: str | None = None
968
+ error: Optional[str] = None
969
969
  """Error message."""
970
- stdout: str | None = None
970
+ stdout: Optional[str] = None
971
971
  """Standard output."""
972
- stderr: str | None = None
972
+ stderr: Optional[str] = None
973
973
  """Standard error."""
974
974
 
975
975
 
@@ -993,9 +993,9 @@ class RunResult(RunInformation):
993
993
  None.
994
994
  """
995
995
 
996
- error_log: ErrorLog | None = None
996
+ error_log: Optional[ErrorLog] = None
997
997
  """Error log of the run. Only available if the run failed."""
998
- output: dict[str, Any] | None = None
998
+ output: Optional[dict[str, Any]] = None
999
999
  """Output of the run. Only available if the run succeeded."""
1000
1000
 
1001
1001
 
@@ -1070,12 +1070,12 @@ class RunQueuing(BaseModel):
1070
1070
  True
1071
1071
  """
1072
1072
 
1073
- priority: int | None = None
1073
+ priority: Optional[int] = None
1074
1074
  """
1075
1075
  Priority of the run in the queue. 1 is the highest priority, 9 is the
1076
1076
  lowest priority.
1077
1077
  """
1078
- disabled: bool | None = None
1078
+ disabled: Optional[bool] = None
1079
1079
  """
1080
1080
  Whether the run should be queued, or not. If True, the run will not be
1081
1081
  queued. If False, the run will be queued.
@@ -1140,21 +1140,21 @@ class RunConfiguration(BaseModel):
1140
1140
  True
1141
1141
  """
1142
1142
 
1143
- execution_class: str | None = None
1143
+ execution_class: Optional[str] = None
1144
1144
  """Execution class for the instance."""
1145
- format: Format | None = None
1145
+ format: Optional[Format] = None
1146
1146
  """Format for the run configuration."""
1147
- run_type: RunTypeConfiguration | None = None
1147
+ run_type: Optional[RunTypeConfiguration] = None
1148
1148
  """Run type configuration for the run."""
1149
- secrets_collection_id: str | None = None
1149
+ secrets_collection_id: Optional[str] = None
1150
1150
  """ID of the secrets collection to use for the run."""
1151
- queuing: RunQueuing | None = None
1151
+ queuing: Optional[RunQueuing] = None
1152
1152
  """Queuing configuration for the run."""
1153
1153
 
1154
1154
  def resolve(
1155
1155
  self,
1156
- input: Input | dict[str, Any] | BaseModel | str,
1157
- dir_path: str | None = None,
1156
+ input: Union[Input, dict[str, Any], BaseModel, str],
1157
+ dir_path: Optional[str] = None,
1158
1158
  ) -> None:
1159
1159
  """
1160
1160
  Resolves the run configuration by modifying or setting the `format`,
@@ -1271,22 +1271,22 @@ class ExternalRunResult(BaseModel):
1271
1271
  'Optimization failed due to invalid constraints'
1272
1272
  """
1273
1273
 
1274
- output_upload_id: str | None = None
1274
+ output_upload_id: Optional[str] = None
1275
1275
  """ID of the output upload."""
1276
- error_upload_id: str | None = None
1276
+ error_upload_id: Optional[str] = None
1277
1277
  """ID of the error upload."""
1278
- status: str | None = None
1278
+ status: Optional[str] = None
1279
1279
  """Status of the run."""
1280
- error_message: str | None = None
1280
+ error_message: Optional[str] = None
1281
1281
  """Error message of the run."""
1282
- execution_duration: int | None = None
1282
+ execution_duration: Optional[int] = None
1283
1283
  """Duration of the run, in milliseconds."""
1284
- statistics_upload_id: str | None = None
1284
+ statistics_upload_id: Optional[str] = None
1285
1285
  """
1286
1286
  ID of the statistics upload. Use this field when working with `CSV_ARCHIVE`
1287
1287
  or `MULTI_FILE` output formats.
1288
1288
  """
1289
- assets_upload_id: str | None = None
1289
+ assets_upload_id: Optional[str] = None
1290
1290
  """
1291
1291
  ID of the assets upload. Use this field when working with `CSV_ARCHIVE`
1292
1292
  or `MULTI_FILE` output formats.
@@ -1466,37 +1466,37 @@ class TrackedRun:
1466
1466
  status: TrackedRunStatus
1467
1467
  """The status of the run being tracked"""
1468
1468
 
1469
- input: Input | dict[str, Any] | str | None = None
1469
+ input: Optional[Union[Input, dict[str, Any], str]] = None
1470
1470
  """
1471
1471
  The input of the run being tracked. Please note that if the input
1472
1472
  format is JSON, then the input data must be JSON serializable. If both
1473
1473
  `input` and `input_dir_path` are specified, the `input` is ignored, and
1474
1474
  the files in the directory are used instead.
1475
1475
  """
1476
- output: Output | dict[str, Any] | str | None = None
1476
+ output: Optional[Union[Output, dict[str, Any], str]] = None
1477
1477
  """
1478
1478
  The output of the run being tracked. Please note that if the output
1479
1479
  format is JSON, then the output data must be JSON serializable. If both
1480
1480
  `output` and `output_dir_path` are specified, the `output` is ignored, and
1481
1481
  the files in the directory are used instead.
1482
1482
  """
1483
- duration: int | None = None
1483
+ duration: Optional[int] = None
1484
1484
  """The duration of the run being tracked, in milliseconds."""
1485
- error: str | None = None
1485
+ error: Optional[str] = None
1486
1486
  """An error message if the run failed. You should only specify this if the
1487
1487
  run failed, otherwise an exception will be raised."""
1488
- logs: list[str] | None = None
1488
+ logs: Optional[list[str]] = None
1489
1489
  """The logs of the run being tracked. Each element of the list is a line in
1490
1490
  the log."""
1491
- name: str | None = None
1491
+ name: Optional[str] = None
1492
1492
  """
1493
1493
  Optional name for the run being tracked.
1494
1494
  """
1495
- description: str | None = None
1495
+ description: Optional[str] = None
1496
1496
  """
1497
1497
  Optional description for the run being tracked.
1498
1498
  """
1499
- input_dir_path: str | None = None
1499
+ input_dir_path: Optional[str] = None
1500
1500
  """
1501
1501
  Path to a directory containing input files. If specified, the calling
1502
1502
  function will package the files in the directory into a tar file and upload
@@ -1505,7 +1505,7 @@ class TrackedRun:
1505
1505
  `input_dir_path` are specified, the `input` is ignored, and the files in
1506
1506
  the directory are used instead.
1507
1507
  """
1508
- output_dir_path: str | None = None
1508
+ output_dir_path: Optional[str] = None
1509
1509
  """
1510
1510
  Path to a directory containing output files. If specified, the calling
1511
1511
  function will package the files in the directory into a tar file and upload
@@ -1514,14 +1514,14 @@ class TrackedRun:
1514
1514
  `output_dir_path` are specified, the `output` is ignored, and the files
1515
1515
  are saved in the directory instead.
1516
1516
  """
1517
- statistics: Statistics | dict[str, Any] | None = None
1517
+ statistics: Optional[Union[Statistics, dict[str, Any]]] = None
1518
1518
  """
1519
1519
  Statistics of the run being tracked. Only use this field if you want to
1520
1520
  track statistics for `CSV_ARCHIVE` or `MULTI_FILE` output formats. If you
1521
1521
  are working with `JSON` or `TEXT` output formats, this field will be
1522
1522
  ignored, as the statistics are extracted directly from the `output`.
1523
1523
  """
1524
- assets: list[Asset | dict[str, Any]] | None = None
1524
+ assets: Optional[list[Union[Asset, dict[str, Any]]]] = None
1525
1525
  """
1526
1526
  Assets associated with the run being tracked. Only use this field if you
1527
1527
  want to track assets for `CSV_ARCHIVE` or `MULTI_FILE` output formats.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nextmv
3
- Version: 0.35.0
3
+ Version: 0.35.0.dev1
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,11 +213,12 @@ 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
216
217
  Classifier: Programming Language :: Python :: 3.10
217
218
  Classifier: Programming Language :: Python :: 3.11
218
219
  Classifier: Programming Language :: Python :: 3.12
219
220
  Classifier: Programming Language :: Python :: 3.13
220
- Requires-Python: >=3.10
221
+ Requires-Python: >=3.9
221
222
  Requires-Dist: pydantic>=2.5.2
222
223
  Requires-Dist: pyyaml>=6.0.1
223
224
  Requires-Dist: requests>=2.31.0
@@ -269,7 +270,7 @@ Welcome to `nextmv`, the general Python SDK for the Nextmv Platform.
269
270
 
270
271
  ## Installation
271
272
 
272
- Requires Python `>=3.10`. Install using `pip`:
273
+ Requires Python `>=3.9`. Install using `pip`:
273
274
 
274
275
  ```bash
275
276
  pip install nextmv