nextmv 0.35.0.dev0__py3-none-any.whl → 0.35.1__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, Optional, Union
63
+ from typing import Any
64
64
 
65
65
  from pydantic import AliasChoices, Field
66
66
 
@@ -119,16 +119,11 @@ class RunStatistics(BaseModel):
119
119
  {'duration': 10.5, 'iterations': 100, 'custom': {'convergence': 0.001}}
120
120
  """
121
121
 
122
- duration: Optional[float] = None
122
+ duration: float | None = None
123
123
  """Duration of the run in seconds."""
124
- iterations: Optional[int] = None
124
+ iterations: int | None = None
125
125
  """Number of iterations."""
126
- custom: Optional[
127
- Union[
128
- Any,
129
- dict[str, Any],
130
- ]
131
- ] = None
126
+ custom: Any | dict[str, Any] | None = None
132
127
  """Custom statistics created by the user. Can normally expect a `dict[str,
133
128
  Any]`."""
134
129
 
@@ -164,16 +159,11 @@ class ResultStatistics(BaseModel):
164
159
  {'duration': 5.2, 'value': 42.0, 'custom': {'gap': 0.05}}
165
160
  """
166
161
 
167
- duration: Optional[float] = None
162
+ duration: float | None = None
168
163
  """Duration of the run in seconds."""
169
- value: Optional[float] = None
164
+ value: float | None = None
170
165
  """Value of the result."""
171
- custom: Optional[
172
- Union[
173
- Any,
174
- dict[str, Any],
175
- ]
176
- ] = None
166
+ custom: Any | dict[str, Any] | None = None
177
167
  """Custom statistics created by the user. Can normally expect a `dict[str,
178
168
  Any]`."""
179
169
 
@@ -239,9 +229,9 @@ class Series(BaseModel):
239
229
  2
240
230
  """
241
231
 
242
- name: Optional[str] = None
232
+ name: str | None = None
243
233
  """Name of the series."""
244
- data_points: Optional[list[DataPoint]] = None
234
+ data_points: list[DataPoint] | None = None
245
235
  """Data of the series."""
246
236
 
247
237
 
@@ -274,9 +264,9 @@ class SeriesData(BaseModel):
274
264
  1
275
265
  """
276
266
 
277
- value: Optional[Series] = None
267
+ value: Series | None = None
278
268
  """A series for the value of the solution."""
279
- custom: Optional[list[Series]] = None
269
+ custom: list[Series] | None = None
280
270
  """A list of series for custom statistics."""
281
271
 
282
272
 
@@ -314,13 +304,13 @@ class Statistics(BaseModel):
314
304
  100.0
315
305
  """
316
306
 
317
- run: Optional[RunStatistics] = None
307
+ run: RunStatistics | None = None
318
308
  """Statistics about the run."""
319
- result: Optional[ResultStatistics] = None
309
+ result: ResultStatistics | None = None
320
310
  """Statistics about the last result."""
321
- series_data: Optional[SeriesData] = None
311
+ series_data: SeriesData | None = None
322
312
  """Data of the series."""
323
- statistics_schema: Optional[str] = Field(
313
+ statistics_schema: str | None = Field(
324
314
  serialization_alias="schema",
325
315
  validation_alias=AliasChoices("schema", "statistics_schema"),
326
316
  default="v1",
@@ -407,7 +397,7 @@ class Visual(BaseModel):
407
397
  label: str
408
398
  """Label for the custom tab of the visual asset in the Nextmv Console."""
409
399
 
410
- visual_type: Optional[str] = Field(
400
+ visual_type: str | None = Field(
411
401
  serialization_alias="type",
412
402
  validation_alias=AliasChoices("type", "visual_type"),
413
403
  default="custom-tab",
@@ -482,11 +472,11 @@ class Asset(BaseModel):
482
472
  content: Any
483
473
  """Content of the asset. The type must be serializable to JSON."""
484
474
 
485
- content_type: Optional[str] = "json"
475
+ content_type: str | None = "json"
486
476
  """Content type of the asset. Only `json` is allowed"""
487
- description: Optional[str] = None
477
+ description: str | None = None
488
478
  """Description of the asset."""
489
- visual: Optional[Visual] = None
479
+ visual: Visual | None = None
490
480
  """Visual schema of the asset."""
491
481
 
492
482
  def __post_init__(self):
@@ -633,12 +623,12 @@ class SolutionFile:
633
623
  The `writer_args` and `writer_kwargs` parameters of this class can be used
634
624
  to provide those additional arguments.
635
625
  """
636
- writer_args: Optional[list[Any]] = None
626
+ writer_args: list[Any] | None = None
637
627
  """
638
628
  Optional positional arguments to pass to the writer function. This can be
639
629
  used to customize the behavior of the writer.
640
630
  """
641
- writer_kwargs: Optional[dict[str, Any]] = None
631
+ writer_kwargs: dict[str, Any] | None = None
642
632
  """
643
633
  Optional keyword arguments to pass to the writer function. This can be used
644
634
  to customize the behavior of the writer.
@@ -648,7 +638,7 @@ class SolutionFile:
648
638
  def json_solution_file(
649
639
  name: str,
650
640
  data: dict[str, Any],
651
- json_configurations: Optional[dict[str, Any]] = None,
641
+ json_configurations: dict[str, Any] | None = None,
652
642
  ) -> SolutionFile:
653
643
  """
654
644
  This is a convenience function to build a `SolutionFile`. It writes the
@@ -711,7 +701,7 @@ def json_solution_file(
711
701
  def csv_solution_file(
712
702
  name: str,
713
703
  data: list[dict[str, Any]],
714
- csv_configurations: Optional[dict[str, Any]] = None,
704
+ csv_configurations: dict[str, Any] | None = None,
715
705
  ) -> SolutionFile:
716
706
  """
717
707
  This is a convenience function to build a `SolutionFile`. It writes the
@@ -933,7 +923,7 @@ class Output:
933
923
  True
934
924
  """
935
925
 
936
- options: Optional[Union[Options, dict[str, Any]]] = None
926
+ options: Options | dict[str, Any] | None = None
937
927
  """
938
928
  Options that the `Output` was created with. These options can be of type
939
929
  `Options` or a simple dictionary. If the options are of type `Options`,
@@ -949,18 +939,13 @@ class Output:
949
939
  }
950
940
  ```
951
941
  """
952
- output_format: Optional[OutputFormat] = OutputFormat.JSON
942
+ output_format: OutputFormat | None = OutputFormat.JSON
953
943
  """
954
944
  Format of the output data. Default is `OutputFormat.JSON`. When set to
955
945
  `OutputFormat.MULTI_FILE`, the `solution_files` field must be specified and
956
946
  cannot be `None`.
957
947
  """
958
- solution: Optional[
959
- Union[
960
- Union[dict[str, Any], Any], # JSON
961
- dict[str, list[dict[str, Any]]], # CSV_ARCHIVE
962
- ]
963
- ] = None
948
+ solution: dict[str, Any] | Any | dict[str, list[dict[str, Any]]] | None = None
964
949
  """
965
950
  The solution to the decision problem. Use this filed when working with
966
951
  `output_format` of types:
@@ -975,7 +960,7 @@ class Output:
975
960
  this `solution` field is ignored, as you should use the `solution_files`
976
961
  field instead.
977
962
  """
978
- statistics: Optional[Union[Statistics, dict[str, Any]]] = None
963
+ statistics: Statistics | dict[str, Any] | None = None
979
964
  """
980
965
  Statistics of the solution. These statistics can be of type `Statistics` or a
981
966
  simple dictionary. If the statistics are of type `Statistics`, they will be
@@ -983,19 +968,19 @@ class Output:
983
968
  dictionary, they will be used as is. If the statistics are not provided, an
984
969
  empty dictionary will be used.
985
970
  """
986
- csv_configurations: Optional[dict[str, Any]] = None
971
+ csv_configurations: dict[str, Any] | None = None
987
972
  """
988
973
  Optional configuration for writing CSV files, to be used when the
989
974
  `output_format` is `OutputFormat.CSV_ARCHIVE`. These configurations are
990
975
  passed as kwargs to the `DictWriter` class from the `csv` module.
991
976
  """
992
- json_configurations: Optional[dict[str, Any]] = None
977
+ json_configurations: dict[str, Any] | None = None
993
978
  """
994
979
  Optional configuration for writing JSON files, to be used when the
995
980
  `output_format` is `OutputFormat.JSON`. These configurations are passed as
996
981
  kwargs to the `json.dumps` function.
997
982
  """
998
- assets: Optional[list[Union[Asset, dict[str, Any]]]] = None
983
+ assets: list[Asset | dict[str, Any]] | None = None
999
984
  """
1000
985
  Optional list of assets to be included in the output. These assets can be of
1001
986
  type `Asset` or a simple dictionary. If the assets are of type `Asset`, they
@@ -1003,7 +988,7 @@ class Output:
1003
988
  dictionary, they will be used as is. If the assets are not provided, an
1004
989
  empty list will be used.
1005
990
  """
1006
- solution_files: Optional[list[SolutionFile]] = None
991
+ solution_files: list[SolutionFile] | None = None
1007
992
  """
1008
993
  Optional list of solution files to be included in the output. These files
1009
994
  are of type `SolutionFile`, which allows for custom serialization and
@@ -1162,7 +1147,7 @@ class OutputWriter:
1162
1147
  ... print(f"Writing output to {path}")
1163
1148
  """
1164
1149
 
1165
- def write(self, output: Union[Output, dict[str, Any], BaseModel], *args, **kwargs) -> None:
1150
+ def write(self, output: Output | dict[str, Any] | BaseModel, *args, **kwargs) -> None:
1166
1151
  """
1167
1152
  Write the output data.
1168
1153
 
@@ -1212,9 +1197,9 @@ class LocalOutputWriter(OutputWriter):
1212
1197
 
1213
1198
  def _write_json(
1214
1199
  self,
1215
- output: Union[Output, dict[str, Any], BaseModel],
1200
+ output: Output | dict[str, Any] | BaseModel,
1216
1201
  output_dict: dict[str, Any],
1217
- path: Optional[str] = None,
1202
+ path: str | None = None,
1218
1203
  ) -> None:
1219
1204
  """
1220
1205
  Write output in JSON format.
@@ -1246,9 +1231,9 @@ class LocalOutputWriter(OutputWriter):
1246
1231
 
1247
1232
  def _write_archive(
1248
1233
  self,
1249
- output: Union[Output, dict[str, Any], BaseModel],
1234
+ output: Output | dict[str, Any] | BaseModel,
1250
1235
  output_dict: dict[str, Any],
1251
- path: Optional[str] = None,
1236
+ path: str | None = None,
1252
1237
  ) -> None:
1253
1238
  """
1254
1239
  Write output in CSV archive format.
@@ -1312,9 +1297,9 @@ class LocalOutputWriter(OutputWriter):
1312
1297
 
1313
1298
  def _write_multi_file(
1314
1299
  self,
1315
- output: Union[Output, dict[str, Any], BaseModel],
1300
+ output: Output | dict[str, Any] | BaseModel,
1316
1301
  output_dict: dict[str, Any],
1317
- path: Optional[str] = None,
1302
+ path: str | None = None,
1318
1303
  ) -> None:
1319
1304
  """
1320
1305
  Write output to multiple files.
@@ -1367,7 +1352,7 @@ class LocalOutputWriter(OutputWriter):
1367
1352
  parent_dir: str,
1368
1353
  output_dict: dict[str, Any],
1369
1354
  element_key: str,
1370
- json_configurations: Optional[dict[str, Any]] = None,
1355
+ json_configurations: dict[str, Any] | None = None,
1371
1356
  ):
1372
1357
  """
1373
1358
  Auxiliary function to write a specific element of the output
@@ -1440,8 +1425,8 @@ class LocalOutputWriter(OutputWriter):
1440
1425
 
1441
1426
  def write(
1442
1427
  self,
1443
- output: Union[Output, dict[str, Any], BaseModel],
1444
- path: Optional[str] = None,
1428
+ output: Output | dict[str, Any] | BaseModel,
1429
+ path: str | None = None,
1445
1430
  skip_stdout_reset: bool = False,
1446
1431
  ) -> None:
1447
1432
  """
@@ -1526,8 +1511,8 @@ class LocalOutputWriter(OutputWriter):
1526
1511
 
1527
1512
 
1528
1513
  def write_local(
1529
- output: Union[Output, dict[str, Any]],
1530
- path: Optional[str] = None,
1514
+ output: Output | dict[str, Any],
1515
+ path: str | None = None,
1531
1516
  skip_stdout_reset: bool = False,
1532
1517
  ) -> None:
1533
1518
  """
@@ -1591,10 +1576,10 @@ _LOCAL_OUTPUT_WRITER = LocalOutputWriter()
1591
1576
 
1592
1577
 
1593
1578
  def write(
1594
- output: Union[Output, dict[str, Any], BaseModel],
1595
- path: Optional[str] = None,
1579
+ output: Output | dict[str, Any] | BaseModel,
1580
+ path: str | None = None,
1596
1581
  skip_stdout_reset: bool = False,
1597
- writer: Optional[OutputWriter] = _LOCAL_OUTPUT_WRITER,
1582
+ writer: OutputWriter | None = _LOCAL_OUTPUT_WRITER,
1598
1583
  ) -> None:
1599
1584
  """
1600
1585
  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, Optional
22
+ from typing import Any
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: Optional[Callable[[], bool]] = None
124
+ stop: Callable[[], bool] | None = 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, Optional, Union
48
+ from typing import Any
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: Union[datetime, float], end: Union[datetime, float]) -> int:
59
+ def run_duration(start: datetime | float, end: 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: Optional[FormatOutput] = Field(
221
+ format_output: FormatOutput | None = 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: Optional[RunType] = Field(
325
+ run_type: RunType | None = 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: Optional[str] = None
331
+ definition_id: str | None = None
332
332
  """ID of the definition for the run type."""
333
- reference_id: Optional[str] = None
333
+ reference_id: str | None = 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: Optional[str] = None
431
+ error: str | None = None
432
432
  """Error message if the statistics could not be retrieved."""
433
- indicators: Optional[list[StatisticsIndicator]] = None
433
+ indicators: list[StatisticsIndicator] | None = 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: Optional[Status] = None
601
+ status: Status | None = None
602
602
  """Deprecated, use status_v2 instead."""
603
- queuing_priority: Optional[int] = None
603
+ queuing_priority: int | None = None
604
604
  """Priority of the run in the queue."""
605
- queuing_disabled: Optional[bool] = None
605
+ queuing_disabled: bool | None = None
606
606
  """Whether the run is disabled from queuing."""
607
- experiment_id: Optional[str] = None
607
+ experiment_id: str | None = None
608
608
  """ID of the experiment associated with the run."""
609
- statistics: Optional[RunInfoStatistics] = None
609
+ statistics: RunInfoStatistics | None = None
610
610
  """Statistics of the run."""
611
- input_id: Optional[str] = None
611
+ input_id: str | None = None
612
612
  """ID of the input associated with the run."""
613
- option_set: Optional[str] = None
613
+ option_set: str | None = None
614
614
  """ID of the option set associated with the run."""
615
- options: Optional[dict[str, str]] = None
615
+ options: dict[str, str] | None = None
616
616
  """Options associated with the run."""
617
- request_options: Optional[dict[str, str]] = None
617
+ request_options: dict[str, str] | None = None
618
618
  """Request options associated with the run."""
619
- options_summary: Optional[list[OptionsSummaryItem]] = None
619
+ options_summary: list[OptionsSummaryItem] | None = None
620
620
  """Summary of options used in the run."""
621
- scenario_id: Optional[str] = None
621
+ scenario_id: str | None = None
622
622
  """ID of the scenario associated with the run."""
623
- repetition: Optional[int] = None
623
+ repetition: int | None = None
624
624
  """Repetition number of the run."""
625
- input_set_id: Optional[str] = None
625
+ input_set_id: str | None = 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: Optional[Status] = None
685
+ status: Status | None = None
686
686
  """Deprecated: use status_v2."""
687
- statistics: Optional[dict[str, Any]] = None
687
+ statistics: dict[str, Any] | None = 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: Optional[str] = None
733
+ instance_id: str | None = 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: Optional[list[SyncedRun]] = None
781
+ synced_runs: list[SyncedRun] | None = 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: Optional[str] = None) -> tuple[SyncedRun, bool]:
910
+ def is_synced(self, app_id: str, instance_id: str | None = 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: Optional[str] = None
968
+ error: str | None = None
969
969
  """Error message."""
970
- stdout: Optional[str] = None
970
+ stdout: str | None = None
971
971
  """Standard output."""
972
- stderr: Optional[str] = None
972
+ stderr: str | None = 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: Optional[ErrorLog] = None
996
+ error_log: ErrorLog | None = None
997
997
  """Error log of the run. Only available if the run failed."""
998
- output: Optional[dict[str, Any]] = None
998
+ output: dict[str, Any] | None = 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: Optional[int] = None
1073
+ priority: int | None = 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: Optional[bool] = None
1078
+ disabled: bool | None = 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: Optional[str] = None
1143
+ execution_class: str | None = None
1144
1144
  """Execution class for the instance."""
1145
- format: Optional[Format] = None
1145
+ format: Format | None = None
1146
1146
  """Format for the run configuration."""
1147
- run_type: Optional[RunTypeConfiguration] = None
1147
+ run_type: RunTypeConfiguration | None = None
1148
1148
  """Run type configuration for the run."""
1149
- secrets_collection_id: Optional[str] = None
1149
+ secrets_collection_id: str | None = None
1150
1150
  """ID of the secrets collection to use for the run."""
1151
- queuing: Optional[RunQueuing] = None
1151
+ queuing: RunQueuing | None = None
1152
1152
  """Queuing configuration for the run."""
1153
1153
 
1154
1154
  def resolve(
1155
1155
  self,
1156
- input: Union[Input, dict[str, Any], BaseModel, str],
1157
- dir_path: Optional[str] = None,
1156
+ input: Input | dict[str, Any] | BaseModel | str,
1157
+ dir_path: str | None = 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: Optional[str] = None
1274
+ output_upload_id: str | None = None
1275
1275
  """ID of the output upload."""
1276
- error_upload_id: Optional[str] = None
1276
+ error_upload_id: str | None = None
1277
1277
  """ID of the error upload."""
1278
- status: Optional[str] = None
1278
+ status: str | None = None
1279
1279
  """Status of the run."""
1280
- error_message: Optional[str] = None
1280
+ error_message: str | None = None
1281
1281
  """Error message of the run."""
1282
- execution_duration: Optional[int] = None
1282
+ execution_duration: int | None = None
1283
1283
  """Duration of the run, in milliseconds."""
1284
- statistics_upload_id: Optional[str] = None
1284
+ statistics_upload_id: str | None = 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: Optional[str] = None
1289
+ assets_upload_id: str | None = 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: Optional[Union[Input, dict[str, Any], str]] = None
1469
+ input: Input | dict[str, Any] | str | None = 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: Optional[Union[Output, dict[str, Any], str]] = None
1476
+ output: Output | dict[str, Any] | str | None = 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: Optional[int] = None
1483
+ duration: int | None = None
1484
1484
  """The duration of the run being tracked, in milliseconds."""
1485
- error: Optional[str] = None
1485
+ error: str | None = 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: Optional[list[str]] = None
1488
+ logs: list[str] | None = 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: Optional[str] = None
1491
+ name: str | None = None
1492
1492
  """
1493
1493
  Optional name for the run being tracked.
1494
1494
  """
1495
- description: Optional[str] = None
1495
+ description: str | None = None
1496
1496
  """
1497
1497
  Optional description for the run being tracked.
1498
1498
  """
1499
- input_dir_path: Optional[str] = None
1499
+ input_dir_path: str | None = 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: Optional[str] = None
1508
+ output_dir_path: str | None = 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: Optional[Union[Statistics, dict[str, Any]]] = None
1517
+ statistics: Statistics | dict[str, Any] | None = 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: Optional[list[Union[Asset, dict[str, Any]]]] = None
1524
+ assets: list[Asset | dict[str, Any]] | None = 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.dev0
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