From 871ba7997efc95f568b1d9c392d6b8f313aa40d6 Mon Sep 17 00:00:00 2001 From: Mattt Zmuda Date: Tue, 7 Nov 2023 03:07:13 -0800 Subject: [PATCH 1/3] Rename BaseModel to Resource Signed-off-by: Mattt Zmuda --- replicate/collection.py | 6 +++--- replicate/deployment.py | 6 +++--- replicate/hardware.py | 6 +++--- replicate/model.py | 6 +++--- replicate/prediction.py | 4 ++-- replicate/{base_model.py => resource.py} | 2 +- replicate/training.py | 4 ++-- replicate/version.py | 4 ++-- 8 files changed, 19 insertions(+), 19 deletions(-) rename replicate/{base_model.py => resource.py} (92%) diff --git a/replicate/collection.py b/replicate/collection.py index b9b8c40a..7f39ad03 100644 --- a/replicate/collection.py +++ b/replicate/collection.py @@ -4,10 +4,10 @@ if TYPE_CHECKING: from replicate.client import Client -from replicate.base_model import BaseModel from replicate.exceptions import ReplicateException +from replicate.resource import Resource -Model = TypeVar("Model", bound=BaseModel) +Model = TypeVar("Model", bound=Resource) class Collection(abc.ABC, Generic[Model]): @@ -25,7 +25,7 @@ def _prepare_model(self, attrs: Union[Model, Dict]) -> Model: """ Create a model from a set of attributes. """ - if isinstance(attrs, BaseModel): + if isinstance(attrs, Resource): attrs._client = self._client attrs._collection = self return cast(Model, attrs) diff --git a/replicate/deployment.py b/replicate/deployment.py index df9bb3c6..830b571f 100644 --- a/replicate/deployment.py +++ b/replicate/deployment.py @@ -1,16 +1,16 @@ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union -from replicate.base_model import BaseModel from replicate.collection import Collection from replicate.files import upload_file from replicate.json import encode_json from replicate.prediction import Prediction +from replicate.resource import Resource if TYPE_CHECKING: from replicate.client import Client -class Deployment(BaseModel): +class Deployment(Resource): """ A deployment of a model hosted on Replicate. """ @@ -59,7 +59,7 @@ def get(self, name: str) -> Deployment: return self._prepare_model({"username": username, "name": name}) def _prepare_model(self, attrs: Union[Deployment, Dict]) -> Deployment: - if isinstance(attrs, BaseModel): + if isinstance(attrs, Resource): attrs.id = f"{attrs.username}/{attrs.name}" elif isinstance(attrs, dict): attrs["id"] = f"{attrs['username']}/{attrs['name']}" diff --git a/replicate/hardware.py b/replicate/hardware.py index 5feee199..4f9070af 100644 --- a/replicate/hardware.py +++ b/replicate/hardware.py @@ -1,10 +1,10 @@ from typing import Dict, List, Union -from replicate.base_model import BaseModel from replicate.collection import Collection +from replicate.resource import Resource -class Hardware(BaseModel): +class Hardware(Resource): """ Hardware for running a model on Replicate. """ @@ -40,7 +40,7 @@ def list(self) -> List[Hardware]: return [self._prepare_model(obj) for obj in hardware] def _prepare_model(self, attrs: Union[Hardware, Dict]) -> Hardware: - if isinstance(attrs, BaseModel): + if isinstance(attrs, Resource): attrs.id = attrs.sku elif isinstance(attrs, dict): attrs["id"] = attrs["sku"] diff --git a/replicate/model.py b/replicate/model.py index 485e2c83..c4965f47 100644 --- a/replicate/model.py +++ b/replicate/model.py @@ -2,14 +2,14 @@ from typing_extensions import deprecated -from replicate.base_model import BaseModel from replicate.collection import Collection from replicate.exceptions import ReplicateException from replicate.prediction import Prediction +from replicate.resource import Resource from replicate.version import Version, VersionCollection -class Model(BaseModel): +class Model(Resource): """ A machine learning model hosted on Replicate. """ @@ -208,7 +208,7 @@ def create( # pylint: disable=arguments-differ disable=too-many-arguments return self._prepare_model(resp.json()) def _prepare_model(self, attrs: Union[Model, Dict]) -> Model: - if isinstance(attrs, BaseModel): + if isinstance(attrs, Resource): attrs.id = f"{attrs.owner}/{attrs.name}" elif isinstance(attrs, dict): attrs["id"] = f"{attrs['owner']}/{attrs['name']}" diff --git a/replicate/prediction.py b/replicate/prediction.py index 9fc69385..b5d8c13f 100644 --- a/replicate/prediction.py +++ b/replicate/prediction.py @@ -3,15 +3,15 @@ from dataclasses import dataclass from typing import Any, Dict, Iterator, List, Optional, Union -from replicate.base_model import BaseModel from replicate.collection import Collection from replicate.exceptions import ModelError from replicate.files import upload_file from replicate.json import encode_json +from replicate.resource import Resource from replicate.version import Version -class Prediction(BaseModel): +class Prediction(Resource): """ A prediction made by a model hosted on Replicate. """ diff --git a/replicate/base_model.py b/replicate/resource.py similarity index 92% rename from replicate/base_model.py rename to replicate/resource.py index 9fac634b..02028660 100644 --- a/replicate/base_model.py +++ b/replicate/resource.py @@ -10,7 +10,7 @@ import pydantic # type: ignore -class BaseModel(pydantic.BaseModel): +class Resource(pydantic.BaseModel): """ A base class for representing a single object on the server. """ diff --git a/replicate/training.py b/replicate/training.py index 6b847fab..cb138dda 100644 --- a/replicate/training.py +++ b/replicate/training.py @@ -3,15 +3,15 @@ from typing_extensions import NotRequired, Unpack, overload -from replicate.base_model import BaseModel from replicate.collection import Collection from replicate.exceptions import ReplicateException from replicate.files import upload_file from replicate.json import encode_json +from replicate.resource import Resource from replicate.version import Version -class Training(BaseModel): +class Training(Resource): """ A training made for a model hosted on Replicate. """ diff --git a/replicate/version.py b/replicate/version.py index 8579b6ae..692a3ecf 100644 --- a/replicate/version.py +++ b/replicate/version.py @@ -7,13 +7,13 @@ from replicate.model import Model -from replicate.base_model import BaseModel from replicate.collection import Collection from replicate.exceptions import ModelError +from replicate.resource import Resource from replicate.schema import make_schema_backwards_compatible -class Version(BaseModel): +class Version(Resource): """ A version of a model. """ From 2522932dbcd309ccaa555839b469c56b1eaffdcb Mon Sep 17 00:00:00 2001 From: Mattt Zmuda Date: Tue, 7 Nov 2023 03:15:53 -0800 Subject: [PATCH 2/3] Rename Collection to Namespace Move Namespace to resource.py Signed-off-by: Mattt Zmuda --- replicate/collection.py | 40 ------------------------------------ replicate/deployment.py | 9 ++++----- replicate/hardware.py | 5 ++--- replicate/model.py | 9 ++++----- replicate/prediction.py | 9 ++++----- replicate/resource.py | 45 ++++++++++++++++++++++++++++++++++++----- replicate/training.py | 9 ++++----- replicate/version.py | 9 ++++----- 8 files changed, 62 insertions(+), 73 deletions(-) delete mode 100644 replicate/collection.py diff --git a/replicate/collection.py b/replicate/collection.py deleted file mode 100644 index 7f39ad03..00000000 --- a/replicate/collection.py +++ /dev/null @@ -1,40 +0,0 @@ -import abc -from typing import TYPE_CHECKING, Dict, Generic, TypeVar, Union, cast - -if TYPE_CHECKING: - from replicate.client import Client - -from replicate.exceptions import ReplicateException -from replicate.resource import Resource - -Model = TypeVar("Model", bound=Resource) - - -class Collection(abc.ABC, Generic[Model]): - """ - A base class for representing objects of a particular type on the server. - """ - - _client: "Client" - model: Model - - def __init__(self, client: "Client") -> None: - self._client = client - - def _prepare_model(self, attrs: Union[Model, Dict]) -> Model: - """ - Create a model from a set of attributes. - """ - if isinstance(attrs, Resource): - attrs._client = self._client - attrs._collection = self - return cast(Model, attrs) - - if isinstance(attrs, dict) and self.model is not None and callable(self.model): - model = self.model(**attrs) - model._client = self._client - model._collection = self - return model - - name = self.model.__name__ if hasattr(self.model, "__name__") else "model" - raise ReplicateException(f"Can't create {name} from {attrs}") diff --git a/replicate/deployment.py b/replicate/deployment.py index 830b571f..36e065ab 100644 --- a/replicate/deployment.py +++ b/replicate/deployment.py @@ -1,10 +1,9 @@ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union -from replicate.collection import Collection from replicate.files import upload_file from replicate.json import encode_json from replicate.prediction import Prediction -from replicate.resource import Resource +from replicate.resource import Namespace, Resource if TYPE_CHECKING: from replicate.client import Client @@ -15,7 +14,7 @@ class Deployment(Resource): A deployment of a model hosted on Replicate. """ - _collection: "DeploymentCollection" + _namespace: "DeploymentCollection" username: str """ @@ -36,7 +35,7 @@ def predictions(self) -> "DeploymentPredictionCollection": return DeploymentPredictionCollection(client=self._client, deployment=self) -class DeploymentCollection(Collection): +class DeploymentCollection(Namespace): """ Namespace for operations related to deployments. """ @@ -66,7 +65,7 @@ def _prepare_model(self, attrs: Union[Deployment, Dict]) -> Deployment: return super()._prepare_model(attrs) -class DeploymentPredictionCollection(Collection): +class DeploymentPredictionCollection(Namespace): """ Namespace for operations related to predictions in a deployment. """ diff --git a/replicate/hardware.py b/replicate/hardware.py index 4f9070af..aa46ea21 100644 --- a/replicate/hardware.py +++ b/replicate/hardware.py @@ -1,7 +1,6 @@ from typing import Dict, List, Union -from replicate.collection import Collection -from replicate.resource import Resource +from replicate.resource import Namespace, Resource class Hardware(Resource): @@ -20,7 +19,7 @@ class Hardware(Resource): """ -class HardwareCollection(Collection): +class HardwareCollection(Namespace): """ Namespace for operations related to hardware. """ diff --git a/replicate/model.py b/replicate/model.py index c4965f47..ddd7667d 100644 --- a/replicate/model.py +++ b/replicate/model.py @@ -2,10 +2,9 @@ from typing_extensions import deprecated -from replicate.collection import Collection from replicate.exceptions import ReplicateException from replicate.prediction import Prediction -from replicate.resource import Resource +from replicate.resource import Namespace, Resource from replicate.version import Version, VersionCollection @@ -14,7 +13,7 @@ class Model(Resource): A machine learning model hosted on Replicate. """ - _collection: "ModelCollection" + _namespace: "ModelCollection" url: str """ @@ -112,12 +111,12 @@ def reload(self) -> None: Load this object from the server. """ - obj = self._collection.get(f"{self.owner}/{self.name}") # pylint: disable=no-member + obj = self._namespace.get(f"{self.owner}/{self.name}") # pylint: disable=no-member for name, value in obj.dict().items(): setattr(self, name, value) -class ModelCollection(Collection): +class ModelCollection(Namespace): """ Namespace for operations related to models. """ diff --git a/replicate/prediction.py b/replicate/prediction.py index b5d8c13f..35f39166 100644 --- a/replicate/prediction.py +++ b/replicate/prediction.py @@ -3,11 +3,10 @@ from dataclasses import dataclass from typing import Any, Dict, Iterator, List, Optional, Union -from replicate.collection import Collection from replicate.exceptions import ModelError from replicate.files import upload_file from replicate.json import encode_json -from replicate.resource import Resource +from replicate.resource import Namespace, Resource from replicate.version import Version @@ -16,7 +15,7 @@ class Prediction(Resource): A prediction made by a model hosted on Replicate. """ - _collection: "PredictionCollection" + _namespace: "PredictionCollection" id: str """The unique ID of the prediction.""" @@ -146,12 +145,12 @@ def reload(self) -> None: Load this prediction from the server. """ - obj = self._collection.get(self.id) # pylint: disable=no-member + obj = self._namespace.get(self.id) # pylint: disable=no-member for name, value in obj.dict().items(): setattr(self, name, value) -class PredictionCollection(Collection): +class PredictionCollection(Namespace): """ Namespace for operations related to predictions. """ diff --git a/replicate/resource.py b/replicate/resource.py index 02028660..9a3473fc 100644 --- a/replicate/resource.py +++ b/replicate/resource.py @@ -1,14 +1,16 @@ -from typing import TYPE_CHECKING +import abc +from typing import TYPE_CHECKING, Dict, Generic, TypeVar, Union, cast -if TYPE_CHECKING: - from replicate.client import Client - from replicate.collection import Collection +from replicate.exceptions import ReplicateException try: from pydantic import v1 as pydantic # type: ignore except ImportError: import pydantic # type: ignore +if TYPE_CHECKING: + from replicate.client import Client + class Resource(pydantic.BaseModel): """ @@ -18,4 +20,37 @@ class Resource(pydantic.BaseModel): id: str _client: "Client" = pydantic.PrivateAttr() - _collection: "Collection" = pydantic.PrivateAttr() + _namespace: "Namespace" = pydantic.PrivateAttr() + + +Model = TypeVar("Model", bound=Resource) + + +class Namespace(abc.ABC, Generic[Model]): + """ + A base class for representing objects of a particular type on the server. + """ + + _client: "Client" + model: Model + + def __init__(self, client: "Client") -> None: + self._client = client + + def _prepare_model(self, attrs: Union[Model, Dict]) -> Model: + """ + Create a model from a set of attributes. + """ + if isinstance(attrs, Resource): + attrs._client = self._client + attrs._namespace = self + return cast(Model, attrs) + + if isinstance(attrs, dict) and self.model is not None and callable(self.model): + model = self.model(**attrs) + model._client = self._client + model._namespace = self + return model + + name = self.model.__name__ if hasattr(self.model, "__name__") else "model" + raise ReplicateException(f"Can't create {name} from {attrs}") diff --git a/replicate/training.py b/replicate/training.py index cb138dda..84b72541 100644 --- a/replicate/training.py +++ b/replicate/training.py @@ -3,11 +3,10 @@ from typing_extensions import NotRequired, Unpack, overload -from replicate.collection import Collection from replicate.exceptions import ReplicateException from replicate.files import upload_file from replicate.json import encode_json -from replicate.resource import Resource +from replicate.resource import Namespace, Resource from replicate.version import Version @@ -16,7 +15,7 @@ class Training(Resource): A training made for a model hosted on Replicate. """ - _collection: "TrainingCollection" + _namespace: "TrainingCollection" id: str """The unique ID of the training.""" @@ -69,12 +68,12 @@ def reload(self) -> None: Load the training from the server. """ - obj = self._collection.get(self.id) # pylint: disable=no-member + obj = self._namespace.get(self.id) # pylint: disable=no-member for name, value in obj.dict().items(): setattr(self, name, value) -class TrainingCollection(Collection): +class TrainingCollection(Namespace): """ Namespace for operations related to trainings. """ diff --git a/replicate/version.py b/replicate/version.py index 692a3ecf..fa3e6a14 100644 --- a/replicate/version.py +++ b/replicate/version.py @@ -7,9 +7,8 @@ from replicate.model import Model -from replicate.collection import Collection from replicate.exceptions import ModelError -from replicate.resource import Resource +from replicate.resource import Namespace, Resource from replicate.schema import make_schema_backwards_compatible @@ -18,7 +17,7 @@ class Version(Resource): A version of a model. """ - _collection: "VersionCollection" + _namespace: "VersionCollection" id: str """The unique ID of the version.""" @@ -70,12 +69,12 @@ def reload(self) -> None: Load this object from the server. """ - obj = self._collection.get(self.id) # pylint: disable=no-member + obj = self._namespace.get(self.id) # pylint: disable=no-member for name, value in obj.dict().items(): setattr(self, name, value) -class VersionCollection(Collection): +class VersionCollection(Namespace): """ Namespace for operations related to model versions. """ From 4c79608b6f3ac1fba8613417eb8e15558171132c Mon Sep 17 00:00:00 2001 From: Mattt Zmuda Date: Tue, 7 Nov 2023 03:18:09 -0800 Subject: [PATCH 3/3] Rename namespace subclasses to replace Collection suffix with plural form Signed-off-by: Mattt Zmuda --- replicate/client.py | 30 +++++++++++++++--------------- replicate/deployment.py | 10 +++++----- replicate/hardware.py | 2 +- replicate/model.py | 10 +++++----- replicate/prediction.py | 4 ++-- replicate/training.py | 4 ++-- replicate/version.py | 4 ++-- 7 files changed, 32 insertions(+), 32 deletions(-) diff --git a/replicate/client.py b/replicate/client.py index 0f2277c2..0a327fef 100644 --- a/replicate/client.py +++ b/replicate/client.py @@ -15,13 +15,13 @@ import httpx from replicate.__about__ import __version__ -from replicate.deployment import DeploymentCollection +from replicate.deployment import Deployments from replicate.exceptions import ModelError, ReplicateError -from replicate.hardware import HardwareCollection -from replicate.model import ModelCollection -from replicate.prediction import PredictionCollection +from replicate.hardware import Hardwares +from replicate.model import Models +from replicate.prediction import Predictions from replicate.schema import make_schema_backwards_compatible -from replicate.training import TrainingCollection +from replicate.training import Trainings from replicate.version import Version @@ -85,39 +85,39 @@ def _request(self, method: str, path: str, **kwargs) -> httpx.Response: return resp @property - def deployments(self) -> DeploymentCollection: + def deployments(self) -> Deployments: """ Namespace for operations related to deployments. """ - return DeploymentCollection(client=self) + return Deployments(client=self) @property - def hardware(self) -> HardwareCollection: + def hardware(self) -> Hardwares: """ Namespace for operations related to hardware. """ - return HardwareCollection(client=self) + return Hardwares(client=self) @property - def models(self) -> ModelCollection: + def models(self) -> Models: """ Namespace for operations related to models. """ - return ModelCollection(client=self) + return Models(client=self) @property - def predictions(self) -> PredictionCollection: + def predictions(self) -> Predictions: """ Namespace for operations related to predictions. """ - return PredictionCollection(client=self) + return Predictions(client=self) @property - def trainings(self) -> TrainingCollection: + def trainings(self) -> Trainings: """ Namespace for operations related to trainings. """ - return TrainingCollection(client=self) + return Trainings(client=self) def run(self, model_version: str, **kwargs) -> Union[Any, Iterator[Any]]: # noqa: ANN401 """ diff --git a/replicate/deployment.py b/replicate/deployment.py index 36e065ab..62a651a4 100644 --- a/replicate/deployment.py +++ b/replicate/deployment.py @@ -14,7 +14,7 @@ class Deployment(Resource): A deployment of a model hosted on Replicate. """ - _namespace: "DeploymentCollection" + _namespace: "Deployments" username: str """ @@ -27,15 +27,15 @@ class Deployment(Resource): """ @property - def predictions(self) -> "DeploymentPredictionCollection": + def predictions(self) -> "DeploymentPredictions": """ Get the predictions for this deployment. """ - return DeploymentPredictionCollection(client=self._client, deployment=self) + return DeploymentPredictions(client=self._client, deployment=self) -class DeploymentCollection(Namespace): +class Deployments(Namespace): """ Namespace for operations related to deployments. """ @@ -65,7 +65,7 @@ def _prepare_model(self, attrs: Union[Deployment, Dict]) -> Deployment: return super()._prepare_model(attrs) -class DeploymentPredictionCollection(Namespace): +class DeploymentPredictions(Namespace): """ Namespace for operations related to predictions in a deployment. """ diff --git a/replicate/hardware.py b/replicate/hardware.py index aa46ea21..1807a2a7 100644 --- a/replicate/hardware.py +++ b/replicate/hardware.py @@ -19,7 +19,7 @@ class Hardware(Resource): """ -class HardwareCollection(Namespace): +class Hardwares(Namespace): """ Namespace for operations related to hardware. """ diff --git a/replicate/model.py b/replicate/model.py index ddd7667d..31825ddd 100644 --- a/replicate/model.py +++ b/replicate/model.py @@ -5,7 +5,7 @@ from replicate.exceptions import ReplicateException from replicate.prediction import Prediction from replicate.resource import Namespace, Resource -from replicate.version import Version, VersionCollection +from replicate.version import Version, Versions class Model(Resource): @@ -13,7 +13,7 @@ class Model(Resource): A machine learning model hosted on Replicate. """ - _namespace: "ModelCollection" + _namespace: "Models" url: str """ @@ -99,12 +99,12 @@ def predict(self, *args, **kwargs) -> None: ) @property - def versions(self) -> VersionCollection: + def versions(self) -> Versions: """ Get the versions of this model. """ - return VersionCollection(client=self._client, model=self) + return Versions(client=self._client, model=self) def reload(self) -> None: """ @@ -116,7 +116,7 @@ def reload(self) -> None: setattr(self, name, value) -class ModelCollection(Namespace): +class Models(Namespace): """ Namespace for operations related to models. """ diff --git a/replicate/prediction.py b/replicate/prediction.py index 35f39166..d6202158 100644 --- a/replicate/prediction.py +++ b/replicate/prediction.py @@ -15,7 +15,7 @@ class Prediction(Resource): A prediction made by a model hosted on Replicate. """ - _namespace: "PredictionCollection" + _namespace: "Predictions" id: str """The unique ID of the prediction.""" @@ -150,7 +150,7 @@ def reload(self) -> None: setattr(self, name, value) -class PredictionCollection(Namespace): +class Predictions(Namespace): """ Namespace for operations related to predictions. """ diff --git a/replicate/training.py b/replicate/training.py index 84b72541..18223bf4 100644 --- a/replicate/training.py +++ b/replicate/training.py @@ -15,7 +15,7 @@ class Training(Resource): A training made for a model hosted on Replicate. """ - _namespace: "TrainingCollection" + _namespace: "Trainings" id: str """The unique ID of the training.""" @@ -73,7 +73,7 @@ def reload(self) -> None: setattr(self, name, value) -class TrainingCollection(Namespace): +class Trainings(Namespace): """ Namespace for operations related to trainings. """ diff --git a/replicate/version.py b/replicate/version.py index fa3e6a14..0496a6a4 100644 --- a/replicate/version.py +++ b/replicate/version.py @@ -17,7 +17,7 @@ class Version(Resource): A version of a model. """ - _namespace: "VersionCollection" + _namespace: "Versions" id: str """The unique ID of the version.""" @@ -74,7 +74,7 @@ def reload(self) -> None: setattr(self, name, value) -class VersionCollection(Namespace): +class Versions(Namespace): """ Namespace for operations related to model versions. """