-
Notifications
You must be signed in to change notification settings - Fork 2
Feature/eng 5549 support ensemble runs via python sdk #143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
ae17f8e
c7b9f7c
e5232a5
6473e36
f0a6f18
a725bed
f996042
d3e2b7e
a186785
750c40d
26ced2d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -22,56 +22,61 @@ | |||||
Function to poll for results with configurable options. | ||||||
""" | ||||||
|
||||||
import json | ||||||
import os | ||||||
import shutil | ||||||
import tarfile | ||||||
import tempfile | ||||||
from dataclasses import dataclass | ||||||
from datetime import datetime | ||||||
from typing import Any, Optional, Union | ||||||
|
||||||
import requests | ||||||
|
||||||
from nextmv._serialization import deflated_serialize_json | ||||||
from nextmv.base_model import BaseModel | ||||||
from nextmv.cloud import package | ||||||
from nextmv.cloud.acceptance_test import AcceptanceTest, Metric | ||||||
from nextmv.cloud.batch_experiment import ( | ||||||
BatchExperiment, | ||||||
BatchExperimentInformation, | ||||||
BatchExperimentMetadata, | ||||||
BatchExperimentRun, | ||||||
ExperimentStatus, | ||||||
to_runs, | ||||||
) | ||||||
from nextmv.cloud.client import Client, get_size | ||||||
from nextmv.cloud.ensemble import ( | ||||||
EnsembleDefinition, | ||||||
RunGroup, | ||||||
EvaluationRule, | ||||||
) | ||||||
from nextmv.cloud.input_set import InputSet, ManagedInput | ||||||
from nextmv.cloud.instance import Instance, InstanceConfiguration | ||||||
from nextmv.cloud.scenario import Scenario, ScenarioInputType, _option_sets, _scenarios_by_id | ||||||
from nextmv.cloud.secrets import Secret, SecretsCollection, SecretsCollectionSummary | ||||||
from nextmv.cloud.url import DownloadURL, UploadURL | ||||||
from nextmv.cloud.version import Version | ||||||
from nextmv.input import Input, InputFormat | ||||||
from nextmv.logger import log | ||||||
from nextmv.manifest import Manifest | ||||||
from nextmv.model import Model, ModelConfiguration | ||||||
from nextmv.options import Options | ||||||
from nextmv.output import Output, OutputFormat | ||||||
from nextmv.polling import DEFAULT_POLLING_OPTIONS, PollingOptions, poll | ||||||
from nextmv.run import ( | ||||||
ExternalRunResult, | ||||||
Format, | ||||||
FormatInput, | ||||||
FormatOutput, | ||||||
RunConfiguration, | ||||||
RunInformation, | ||||||
RunLog, | ||||||
RunResult, | ||||||
TrackedRun, | ||||||
) | ||||||
from nextmv.safe import safe_id, safe_name_and_id | ||||||
from nextmv.status import StatusV2 | ||||||
Check failure on line 79 in nextmv/nextmv/cloud/application.py
|
||||||
|
||||||
# Maximum size of the run input/output in bytes. This constant defines the | ||||||
# maximum allowed size for run inputs and outputs. When the size exceeds this | ||||||
|
@@ -551,6 +556,30 @@ | |||||
endpoint=f"{self.endpoint}/secrets/{secrets_collection_id}", | ||||||
) | ||||||
|
||||||
def delete_ensemble_definition(self, ensemble_definition_id: str) -> None: | ||||||
|
||||||
""" | ||||||
Delete a secrets collection. | ||||||
|
||||||
|
||||||
Parameters | ||||||
---------- | ||||||
ensemble_definition_id : str | ||||||
ID of the ensemble definition to delete. | ||||||
|
||||||
Raises | ||||||
------ | ||||||
requests.HTTPError | ||||||
If the response status code is not 2xx. | ||||||
|
||||||
Examples | ||||||
-------- | ||||||
>>> app.delete_ensemble_definition("development-ensemble-definition") | ||||||
""" | ||||||
|
||||||
_ = self.client.request( | ||||||
method="DELETE", | ||||||
endpoint=f"{self.endpoint}/ensembles/{ensemble_definition_id}", | ||||||
) | ||||||
|
||||||
@staticmethod | ||||||
def exists(client: Client, id: str) -> bool: | ||||||
""" | ||||||
|
@@ -683,6 +712,39 @@ | |||||
return False | ||||||
raise e | ||||||
|
||||||
def ensemble_definition(self, ensemble_definition_id: str) -> EnsembleDefinition: | ||||||
|
||||||
""" | ||||||
Get an ensemble definition. | ||||||
|
||||||
Parameters | ||||||
---------- | ||||||
ensemble_definition_id : str | ||||||
ID of the ensemble definition to retrieve. | ||||||
|
||||||
Returns | ||||||
------- | ||||||
EnsembleDefintion | ||||||
The requested ensemble definition details. | ||||||
|
||||||
Raises | ||||||
------ | ||||||
requests.HTTPError | ||||||
If the response status code is not 2xx. | ||||||
|
||||||
Examples | ||||||
-------- | ||||||
>>> ensemble_definition = app.ensemble_definition("instance-123") | ||||||
>>> print(ensemble_definition.name) | ||||||
'Production Ensemble Definition' | ||||||
""" | ||||||
|
||||||
response = self.client.request( | ||||||
method="GET", | ||||||
endpoint=f"{self.endpoint}/ensembles/{ensemble_definition_id}", | ||||||
) | ||||||
|
||||||
return EnsembleDefinition.from_dict(response.json()) | ||||||
|
||||||
def list_acceptance_tests(self) -> list[AcceptanceTest]: | ||||||
""" | ||||||
List all acceptance tests. | ||||||
|
@@ -796,6 +858,36 @@ | |||||
|
||||||
return [Instance.from_dict(instance) for instance in response.json()] | ||||||
|
||||||
def list_ensemble_definitions(self) -> list[EnsembleDefinition]: | ||||||
|
||||||
""" | ||||||
List all ensemble_definitions. | ||||||
|
||||||
Returns | ||||||
------- | ||||||
list['EnsembleDefinition'] | ||||||
|
list['EnsembleDefinition'] | |
list[EnsembleDefinition] |
I think in this case backticks are not needed.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Parameters should be in the same order they are expected in the function arguments.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: consider defining ensembles
as an attribute of the class, similar to experiments_endpoint
:
experiments_endpoint: str = "{base}/experiments"
That way, you can use {self.ensembles_endpoint}
as opposed to {self.endpoint}/ensembles
here and in other places.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: same comment about alphabetical order.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strange, this should be ok.