nextmv 0.25.0__py3-none-any.whl → 0.26.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 CHANGED
@@ -1 +1 @@
1
- __version__ = "v0.25.0"
1
+ __version__ = "v0.26.0"
@@ -14,7 +14,12 @@ import requests
14
14
  from nextmv.base_model import BaseModel
15
15
  from nextmv.cloud import package
16
16
  from nextmv.cloud.acceptance_test import AcceptanceTest, ExperimentStatus, Metric
17
- from nextmv.cloud.batch_experiment import BatchExperiment, BatchExperimentMetadata, BatchExperimentRun
17
+ from nextmv.cloud.batch_experiment import (
18
+ BatchExperiment,
19
+ BatchExperimentInformation,
20
+ BatchExperimentMetadata,
21
+ BatchExperimentRun,
22
+ )
18
23
  from nextmv.cloud.client import Client, get_size
19
24
  from nextmv.cloud.input_set import InputSet, ManagedInput
20
25
  from nextmv.cloud.instance import Instance, InstanceConfiguration
@@ -1955,6 +1960,47 @@ class Application:
1955
1960
 
1956
1961
  return Instance.from_dict(response.json())
1957
1962
 
1963
+ def update_batch_experiment(
1964
+ self,
1965
+ batch_experiment_id: str,
1966
+ name: str,
1967
+ description: str,
1968
+ ) -> BatchExperimentInformation:
1969
+ """
1970
+ Update a batch experiment.
1971
+
1972
+ Parameters
1973
+ ----------
1974
+ batch_experiment_id : str
1975
+ ID of the batch experiment to update.
1976
+ name : str
1977
+ Name of the batch experiment.
1978
+ description : str
1979
+ Description of the batch experiment.
1980
+
1981
+ Returns
1982
+ -------
1983
+ BatchExperimentInformation
1984
+ The information with the updated batch experiment.
1985
+
1986
+ Raises
1987
+ ------
1988
+ requests.HTTPError
1989
+ If the response status code is not 2xx.
1990
+ """
1991
+
1992
+ payload = {
1993
+ "name": name,
1994
+ "description": description,
1995
+ }
1996
+ response = self.client.request(
1997
+ method="PATCH",
1998
+ endpoint=f"{self.experiments_endpoint}/batch/{batch_experiment_id}",
1999
+ payload=payload,
2000
+ )
2001
+
2002
+ return BatchExperimentInformation.from_dict(response.json())
2003
+
1958
2004
  def update_managed_input(
1959
2005
  self,
1960
2006
  managed_input_id: str,
@@ -1994,6 +2040,43 @@ class Application:
1994
2040
  payload=payload,
1995
2041
  )
1996
2042
 
2043
+ def update_scenario_test(
2044
+ self,
2045
+ scenario_test_id: str,
2046
+ name: str,
2047
+ description: str,
2048
+ ) -> BatchExperimentInformation:
2049
+ """
2050
+ Update a scenario test. Scenario tests use the batch experiments API,
2051
+ so this method calls the `update_batch_experiment` method, and thus the
2052
+ return type is the same.
2053
+
2054
+ Parameters
2055
+ ----------
2056
+ scenario_test_id : str
2057
+ ID of the scenario test to update.
2058
+ name : str
2059
+ Name of the scenario test.
2060
+ description : str
2061
+ Description of the scenario test.
2062
+
2063
+ Returns
2064
+ -------
2065
+ BatchExperimentInformation
2066
+ The information with the updated scenario test.
2067
+
2068
+ Raises
2069
+ ------
2070
+ requests.HTTPError
2071
+ If the response status code is not 2xx.
2072
+ """
2073
+
2074
+ return self.update_batch_experiment(
2075
+ batch_experiment_id=scenario_test_id,
2076
+ name=name,
2077
+ description=description,
2078
+ )
2079
+
1997
2080
  def update_secrets_collection(
1998
2081
  self,
1999
2082
  secrets_collection_id: str,
@@ -18,9 +18,9 @@ class BatchExperimentInformation(BaseModel):
18
18
  """Creation date of the batch experiment."""
19
19
  updated_at: datetime
20
20
  """Last update date of the batch experiment."""
21
- status: str
22
- """Status of the batch experiment."""
23
21
 
22
+ status: Optional[str] = None
23
+ """Status of the batch experiment."""
24
24
  description: Optional[str] = None
25
25
  """Description of the batch experiment."""
26
26
  number_of_requested_runs: Optional[int] = None
@@ -101,5 +101,5 @@ class BatchExperimentRun(BaseModel):
101
101
  class BatchExperimentMetadata(BatchExperimentInformation):
102
102
  """Metadata of a batch experiment."""
103
103
 
104
- app_id: str
104
+ app_id: Optional[str] = None
105
105
  """ID of the application used for the batch experiment."""
nextmv/output.py CHANGED
@@ -349,7 +349,7 @@ class Output:
349
349
  class OutputWriter:
350
350
  """Base class for writing outputs."""
351
351
 
352
- def write(self, output: Output, *args, **kwargs) -> None:
352
+ def write(self, output: Union[Output, dict[str, Any], BaseModel], *args, **kwargs) -> None:
353
353
  """
354
354
  Write the output data. This method should be implemented by subclasses.
355
355
  """
@@ -364,7 +364,7 @@ class LocalOutputWriter(OutputWriter):
364
364
  """
365
365
 
366
366
  def _write_json(
367
- output: Union[Output, dict[str, Any]],
367
+ output: Union[Output, dict[str, Any], BaseModel],
368
368
  options: dict[str, Any],
369
369
  statistics: dict[str, Any],
370
370
  assets: list[dict[str, Any]],
@@ -372,6 +372,8 @@ class LocalOutputWriter(OutputWriter):
372
372
  ) -> None:
373
373
  if isinstance(output, dict):
374
374
  final_output = output
375
+ elif isinstance(output, BaseModel):
376
+ final_output = output.to_dict()
375
377
  else:
376
378
  solution = output.solution if output.solution is not None else {}
377
379
  final_output = {
@@ -447,7 +449,7 @@ class LocalOutputWriter(OutputWriter):
447
449
 
448
450
  def write(
449
451
  self,
450
- output: Union[Output, dict[str, Any]],
452
+ output: Union[Output, dict[str, Any], BaseModel],
451
453
  path: Optional[str] = None,
452
454
  skip_stdout_reset: bool = False,
453
455
  ) -> None:
@@ -497,8 +499,12 @@ class LocalOutputWriter(OutputWriter):
497
499
  output_format = output.output_format
498
500
  elif isinstance(output, dict):
499
501
  output_format = OutputFormat.JSON
502
+ elif isinstance(output, BaseModel):
503
+ output_format = OutputFormat.JSON
500
504
  else:
501
- raise TypeError(f"unsupported output type: {type(output)}, supported types are `Output` or `dict`")
505
+ raise TypeError(
506
+ f"unsupported output type: {type(output)}, supported types are `Output`, `dict`, `BaseModel`"
507
+ )
502
508
 
503
509
  statistics = self._extract_statistics(output)
504
510
  options = self._extract_options(output)
@@ -640,7 +646,7 @@ _LOCAL_OUTPUT_WRITER = LocalOutputWriter()
640
646
 
641
647
 
642
648
  def write(
643
- output: Union[Output, dict[str, Any]],
649
+ output: Union[Output, dict[str, Any], BaseModel],
644
650
  path: Optional[str] = None,
645
651
  skip_stdout_reset: bool = False,
646
652
  writer: Optional[OutputWriter] = _LOCAL_OUTPUT_WRITER,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nextmv
3
- Version: 0.25.0
3
+ Version: 0.26.0
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://www.nextmv.io/docs/python-sdks/nextmv/installation
@@ -1,4 +1,4 @@
1
- nextmv/__about__.py,sha256=T6lSUpF45beuL-c-KeOs9kKTHrB_ym1u_UF73VJuAG0,24
1
+ nextmv/__about__.py,sha256=eQqPiK0rRHZ8N7lI25IAshYTaILxk2NZzxVXgTPB1OY,24
2
2
  nextmv/__entrypoint__.py,sha256=5K058PICm5sx4sNMqx56auMh9yWgdIESVLzfvyIXdjs,1158
3
3
  nextmv/__init__.py,sha256=QN5e_BFkIdBkR8DiGr9T06N6mXtowT84eRUJj3_Vfrg,1459
4
4
  nextmv/base_model.py,sha256=mdaBe-epNK1cFgP4TxbOtn3So4pCi1vMTOrIBkCBp7A,1050
@@ -7,12 +7,12 @@ nextmv/input.py,sha256=tppXHiJM_EzR9Z1yJPc37joBvgC0RmiAFo0Ab1X5nPA,15480
7
7
  nextmv/logger.py,sha256=5qQ7E3Aaw3zzkIeiUuwYGzTcB7VhVqIzNZm5PHmdpUI,852
8
8
  nextmv/model.py,sha256=rwBdgmKSEp1DPv43zF0azj3QnbHO6O6wKs0PIGvVS40,9861
9
9
  nextmv/options.py,sha256=IPqAIUjoKMWmoPx_e5zDcnxu7S2HVxw-SLjjUduVvZM,25302
10
- nextmv/output.py,sha256=xag6SoNkd3oyKBgQCbvx6jsYLu4pzHPuLEAEtbCDolI,21984
10
+ nextmv/output.py,sha256=rcmDivGRsInyS944ivO6SBtVFSH3RC5Nwu0qFTFRRLI,22270
11
11
  nextmv/cloud/__init__.py,sha256=O34rjrgClnIwXDE63PK4iq5ESuGQ86dJ6FPSrcUnmk0,3680
12
12
  nextmv/cloud/acceptance_test.py,sha256=NtqGhj-UYibxGBbU2kfjr-lYcngojb_5VMvK2WZwibI,6620
13
13
  nextmv/cloud/account.py,sha256=mZUGzV-uMGBA5BC_FPtsiCMFuz5jxEZ3O1BbELZIm18,1841
14
- nextmv/cloud/application.py,sha256=l9cC9HlBX8eAv8IlFzA9mvQzRMmNB72IAG_4WtLAzbU,79801
15
- nextmv/cloud/batch_experiment.py,sha256=xuItiW0hhaDt78BWSz7bcw8cbI8joCkw5KH2Gj5JRbQ,3734
14
+ nextmv/cloud/application.py,sha256=BoW-n_cJ4nxpmxOq_VMdJzv7B4RSxRhApkv0_oEcEYQ,81952
15
+ nextmv/cloud/batch_experiment.py,sha256=Ngm1XDvvAMaU9VYU5JFNxXFnt8xjE_34H5W54kO9V5c,3768
16
16
  nextmv/cloud/client.py,sha256=JUE3vD767_FFICl1vov5Mxmircci03TBL3KmT1BOZY4,9096
17
17
  nextmv/cloud/input_set.py,sha256=HTLA2acJridZbBCAVJNom8ldNo2Rfy40YQ8Coyz3bdo,1482
18
18
  nextmv/cloud/instance.py,sha256=UfyfZXfL1ugCGAB6zwZJIAi8qxI1JCUGsluwaGdjfN4,1223
@@ -24,7 +24,7 @@ nextmv/cloud/scenario.py,sha256=9gbdnQuvmerPUBCcJ-5QbLCwgbsIfBwKXE8c5359S8E,8120
24
24
  nextmv/cloud/secrets.py,sha256=kqlN4ceww_L4kVTrAU8BZykRzXINO3zhMT_BLYea6tk,1764
25
25
  nextmv/cloud/status.py,sha256=C-ax8cLw0jPeh7CPsJkCa0s4ImRyFI4NDJJxI0_1sr4,602
26
26
  nextmv/cloud/version.py,sha256=sjVRNRtohHA97j6IuyM33_DSSsXYkZPusYgpb6hlcrc,1244
27
- nextmv-0.25.0.dist-info/METADATA,sha256=ha-JGTm1OXZqs4mi9fmTA3mqsT4ZdMd4izLoOGG_cck,14557
28
- nextmv-0.25.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
29
- nextmv-0.25.0.dist-info/licenses/LICENSE,sha256=ZIbK-sSWA-OZprjNbmJAglYRtl5_K4l9UwAV3PGJAPc,11349
30
- nextmv-0.25.0.dist-info/RECORD,,
27
+ nextmv-0.26.0.dist-info/METADATA,sha256=c53wSmLfDD0omHMTPlxDkrx9DMb5RdvKMNHCByar1TA,14557
28
+ nextmv-0.26.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
29
+ nextmv-0.26.0.dist-info/licenses/LICENSE,sha256=ZIbK-sSWA-OZprjNbmJAglYRtl5_K4l9UwAV3PGJAPc,11349
30
+ nextmv-0.26.0.dist-info/RECORD,,