Skip to content

Commit db51ee0

Browse files
authored
Remove id field from Resource (#191)
Related to #188 API resources define a common `id` field, which requires additional bookkeeping in `_prepare_model`. However, these fields aren't used, and either shadow a field on the resource or can be computed. This PR removes `id` from the base model, adds properties for subclasses that don't have an `id` field (like `Hardware` and `Collection`), and marks them as deprecated, for anyone who is relying on that behavior. --------- Signed-off-by: Mattt Zmuda <mattt@replicate.com>
1 parent b6a3dff commit db51ee0

File tree

5 files changed

+31
-28
lines changed

5 files changed

+31
-28
lines changed

replicate/collection.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from typing import TYPE_CHECKING, Dict, List, Optional, Union
22

3+
from typing_extensions import deprecated
4+
35
from replicate.model import Model, Models
46
from replicate.pagination import Page
57
from replicate.resource import Namespace, Resource
@@ -25,6 +27,14 @@ class Collection(Resource):
2527
models: Optional[List[Model]] = None
2628
"""The models in the collection."""
2729

30+
@property
31+
@deprecated("Use `slug` instead of `id`")
32+
def id(self) -> str:
33+
"""
34+
DEPRECATED: Use `slug` instead.
35+
"""
36+
return self.slug
37+
2838
def __iter__(self): # noqa: ANN204
2939
return iter(self.models)
3040

@@ -90,13 +100,9 @@ def get(self, slug: str) -> Collection:
90100

91101
def _prepare_model(self, attrs: Union[Collection, Dict]) -> Collection:
92102
if isinstance(attrs, Resource):
93-
attrs.id = attrs.slug
94-
95103
if attrs.models is not None:
96104
attrs.models = [self._models._prepare_model(m) for m in attrs.models]
97105
elif isinstance(attrs, dict):
98-
attrs["id"] = attrs["slug"]
99-
100106
if "models" in attrs:
101107
attrs["models"] = [
102108
self._models._prepare_model(m) for m in attrs["models"]

replicate/deployment.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
1+
from typing import TYPE_CHECKING, Any, Dict, List, Optional
22

33
from replicate.files import upload_file
44
from replicate.json import encode_json
@@ -26,6 +26,10 @@ class Deployment(Resource):
2626
The name of the deployment.
2727
"""
2828

29+
@property
30+
def id(self) -> str:
31+
return f"{self.username}/{self.name}"
32+
2933
@property
3034
def predictions(self) -> "DeploymentPredictions":
3135
"""
@@ -57,13 +61,6 @@ def get(self, name: str) -> Deployment:
5761
username, name = name.split("/")
5862
return self._prepare_model({"username": username, "name": name})
5963

60-
def _prepare_model(self, attrs: Union[Deployment, Dict]) -> Deployment:
61-
if isinstance(attrs, Resource):
62-
attrs.id = f"{attrs.username}/{attrs.name}"
63-
elif isinstance(attrs, dict):
64-
attrs["id"] = f"{attrs['username']}/{attrs['name']}"
65-
return super()._prepare_model(attrs)
66-
6764

6865
class DeploymentPredictions(Namespace):
6966
"""

replicate/hardware.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
from typing import Dict, List, Union
1+
from typing import List
2+
3+
from typing_extensions import deprecated
24

35
from replicate.resource import Namespace, Resource
46

@@ -18,6 +20,14 @@ class Hardware(Resource):
1820
The name of the hardware.
1921
"""
2022

23+
@property
24+
@deprecated("Use `sku` instead of `id`")
25+
def id(self) -> str:
26+
"""
27+
DEPRECATED: Use `sku` instead.
28+
"""
29+
return self.sku
30+
2131

2232
class Hardwares(Namespace):
2333
"""
@@ -36,11 +46,3 @@ def list(self) -> List[Hardware]:
3646

3747
resp = self._client._request("GET", "/v1/hardware")
3848
return [self._prepare_model(obj) for obj in resp.json()]
39-
40-
def _prepare_model(self, attrs: Union[Hardware, Dict]) -> Hardware:
41-
if isinstance(attrs, Resource):
42-
attrs.id = attrs.sku
43-
elif isinstance(attrs, dict):
44-
attrs["id"] = attrs["sku"]
45-
46-
return super()._prepare_model(attrs)

replicate/model.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ class Model(Resource):
7676
The latest version of the model.
7777
"""
7878

79+
@property
80+
def id(self) -> str:
81+
return f"{self.owner}/{self.name}"
82+
7983
@property
8084
@deprecated("Use `model.owner` instead.")
8185
def username(self) -> str:
@@ -213,11 +217,7 @@ def create( # pylint: disable=arguments-differ disable=too-many-arguments
213217
return self._prepare_model(resp.json())
214218

215219
def _prepare_model(self, attrs: Union[Model, Dict]) -> Model:
216-
if isinstance(attrs, Resource):
217-
attrs.id = f"{attrs.owner}/{attrs.name}"
218-
elif isinstance(attrs, dict):
219-
attrs["id"] = f"{attrs['owner']}/{attrs['name']}"
220-
220+
if isinstance(attrs, dict):
221221
if attrs is not None:
222222
if "default_example" in attrs and attrs["default_example"]:
223223
attrs["default_example"].pop("version")

replicate/resource.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ class Resource(pydantic.BaseModel):
1717
A base class for representing a single object on the server.
1818
"""
1919

20-
id: str
21-
2220
_client: "Client" = pydantic.PrivateAttr()
2321
_namespace: "Namespace" = pydantic.PrivateAttr()
2422

0 commit comments

Comments
 (0)