Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 3173e5f

Browse files
feat(api): add Files API methods
...and mark them as undocumented.
1 parent c36bf61 commit 3173e5f

File tree

19 files changed

+1544
-158
lines changed

19 files changed

+1544
-158
lines changed

‎.stats.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
configured_endpoints: 30
1+
configured_endpoints: 35
22
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/replicate%2Freplicate-client-efbc8cc2d74644b213e161d3e11e0589d1cef181fb318ea02c8eb6b00f245713.yml
33
openapi_spec_hash: 13da0c06c900b61cd98ab678e024987a
4-
config_hash: 927b6ebc00ee115763ad69483bbf5566
4+
config_hash: e25b98bb6202d27e54fc6e08c7de80d8

‎README.md‎

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,17 @@ import os
2828
from replicate import Replicate
2929

3030
client = Replicate(
31-
bearer_token=os.environ.get("REPLICATE_API_TOKEN"), # This is the default and can be omitted
31+
api_key=os.environ.get("REPLICATE_CLIENT_API_KEY"), # This is the default and can be omitted
3232
)
3333

3434
account = client.account.get()
3535
print(account.type)
3636
```
3737

38-
While you can provide a `bearer_token` keyword argument,
38+
While you can provide an `api_key` keyword argument,
3939
we recommend using [python-dotenv](https://pypi.org/project/python-dotenv/)
40-
to add `REPLICATE_API_TOKEN="My Bearer Token"` to your `.env` file
41-
so that your Bearer Token is not stored in source control.
40+
to add `REPLICATE_CLIENT_API_KEY="My API Key"` to your `.env` file
41+
so that your API Key is not stored in source control.
4242

4343
## Async usage
4444

@@ -50,7 +50,7 @@ import asyncio
5050
from replicate import AsyncReplicate
5151

5252
client = AsyncReplicate(
53-
bearer_token=os.environ.get("REPLICATE_API_TOKEN"), # This is the default and can be omitted
53+
api_key=os.environ.get("REPLICATE_CLIENT_API_KEY"), # This is the default and can be omitted
5454
)
5555

5656

@@ -136,6 +136,24 @@ for prediction in first_page.results:
136136
# Remove `await` for non-async usage.
137137
```
138138

139+
## File uploads
140+
141+
Request parameters that correspond to file uploads can be passed as `bytes`, or a [`PathLike`](https://docs.python.org/3/library/os.html#os.PathLike) instance or a tuple of `(filename, contents, media type)`.
142+
143+
```python
144+
from pathlib import Path
145+
from replicate import Replicate
146+
147+
client = Replicate()
148+
149+
client.files.create(
150+
content=Path("/path/to/file"),
151+
filename="filename",
152+
)
153+
```
154+
155+
The async client uses the exact same interface. If you pass a [`PathLike`](https://docs.python.org/3/library/os.html#os.PathLike) instance, the file contents will be read asynchronously automatically.
156+
139157
## Handling errors
140158

141159
When the library is unable to connect to the API (for example, due to network connection problems or a timeout), a subclass of `replicate.APIConnectionError` is raised.

‎api.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,11 @@ from replicate.types.webhooks.default import SecretGetResponse
154154
Methods:
155155

156156
- <code title="get /webhooks/default/secret">client.webhooks.default.secret.<a href="./src/replicate/resources/webhooks/default/secret.py">get</a>() -> <a href="./src/replicate/types/webhooks/default/secret_get_response.py">SecretGetResponse</a></code>
157+
158+
# Files
159+
160+
Types:
161+
162+
```python
163+
from replicate.types import FileCreateResponse, FileListResponse, FileGetResponse
164+
```

‎src/replicate/__init__.py‎

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104

105105
from ._base_client import DEFAULT_TIMEOUT, DEFAULT_MAX_RETRIES
106106

107-
bearer_token: str | None = None
107+
api_key: str | None = None
108108

109109
base_url: str | _httpx.URL | None = None
110110

@@ -125,14 +125,14 @@ class _ModuleClient(Replicate):
125125

126126
@property # type: ignore
127127
@override
128-
def bearer_token(self) -> str | None:
129-
return bearer_token
128+
def api_key(self) -> str | None:
129+
return api_key
130130

131-
@bearer_token.setter # type: ignore
132-
def bearer_token(self, value: str | None) -> None: # type: ignore
133-
global bearer_token
131+
@api_key.setter # type: ignore
132+
def api_key(self, value: str | None) -> None: # type: ignore
133+
global api_key
134134

135-
bearer_token = value
135+
api_key = value
136136

137137
@property
138138
@override
@@ -210,7 +210,7 @@ def _load_client() -> Replicate: # type: ignore[reportUnusedFunction]
210210

211211
if _client is None:
212212
_client = _ModuleClient(
213-
bearer_token=bearer_token,
213+
api_key=api_key,
214214
base_url=base_url,
215215
timeout=timeout,
216216
max_retries=max_retries,
@@ -230,6 +230,7 @@ def _reset_client() -> None: # type: ignore[reportUnusedFunction]
230230

231231

232232
from ._module_client import (
233+
files as files,
233234
models as models,
234235
account as account,
235236
hardware as hardware,

‎src/replicate/_client.py‎

Lines changed: 62 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
)
3232

3333
if TYPE_CHECKING:
34-
from .resources import models, account, hardware, webhooks, trainings, collections, deployments, predictions
34+
from .resources import files, models, account, hardware, webhooks, trainings, collections, deployments, predictions
35+
from .resources.files import FilesResource, AsyncFilesResource
3536
from .resources.account import AccountResource, AsyncAccountResource
3637
from .resources.hardware import HardwareResource, AsyncHardwareResource
3738
from .resources.trainings import TrainingsResource, AsyncTrainingsResource
@@ -55,12 +56,12 @@
5556

5657
class Replicate(SyncAPIClient):
5758
# client options
58-
bearer_token: str
59+
api_key: str
5960

6061
def __init__(
6162
self,
6263
*,
63-
bearer_token: str | None = None,
64+
api_key: str | None = None,
6465
base_url: str | httpx.URL | None = None,
6566
timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN,
6667
max_retries: int = DEFAULT_MAX_RETRIES,
@@ -82,15 +83,15 @@ def __init__(
8283
) -> None:
8384
"""Construct a new synchronous Replicate client instance.
8485
85-
This automatically infers the `bearer_token` argument from the `REPLICATE_API_TOKEN` environment variable if it is not provided.
86+
This automatically infers the `api_key` argument from the `REPLICATE_CLIENT_API_KEY` environment variable if it is not provided.
8687
"""
87-
if bearer_token is None:
88-
bearer_token = os.environ.get("REPLICATE_API_TOKEN")
89-
if bearer_token is None:
88+
if api_key is None:
89+
api_key = os.environ.get("REPLICATE_CLIENT_API_KEY")
90+
if api_key is None:
9091
raise ReplicateError(
91-
"The bearer_token client option must be set either by passing bearer_token to the client or by setting the REPLICATE_API_TOKEN environment variable"
92+
"The api_key client option must be set either by passing api_key to the client or by setting the REPLICATE_CLIENT_API_KEY environment variable"
9293
)
93-
self.bearer_token = bearer_token
94+
self.api_key = api_key
9495

9596
if base_url is None:
9697
base_url = os.environ.get("REPLICATE_BASE_URL")
@@ -156,6 +157,12 @@ def webhooks(self) -> WebhooksResource:
156157

157158
return WebhooksResource(self)
158159

160+
@cached_property
161+
def files(self) -> FilesResource:
162+
from .resources.files import FilesResource
163+
164+
return FilesResource(self)
165+
159166
@cached_property
160167
def with_raw_response(self) -> ReplicateWithRawResponse:
161168
return ReplicateWithRawResponse(self)
@@ -172,8 +179,8 @@ def qs(self) -> Querystring:
172179
@property
173180
@override
174181
def auth_headers(self) -> dict[str, str]:
175-
bearer_token = self.bearer_token
176-
return {"Authorization": f"Bearer {bearer_token}"}
182+
api_key = self.api_key
183+
return {"Authorization": f"Bearer {api_key}"}
177184

178185
@property
179186
@override
@@ -187,7 +194,7 @@ def default_headers(self) -> dict[str, str | Omit]:
187194
def copy(
188195
self,
189196
*,
190-
bearer_token: str | None = None,
197+
api_key: str | None = None,
191198
base_url: str | httpx.URL | None = None,
192199
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
193200
http_client: httpx.Client | None = None,
@@ -221,7 +228,7 @@ def copy(
221228

222229
http_client = http_client or self._client
223230
return self.__class__(
224-
bearer_token=bearer_token or self.bearer_token,
231+
api_key=api_key or self.api_key,
225232
base_url=base_url or self.base_url,
226233
timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
227234
http_client=http_client,
@@ -271,12 +278,12 @@ def _make_status_error(
271278

272279
class AsyncReplicate(AsyncAPIClient):
273280
# client options
274-
bearer_token: str
281+
api_key: str
275282

276283
def __init__(
277284
self,
278285
*,
279-
bearer_token: str | None = None,
286+
api_key: str | None = None,
280287
base_url: str | httpx.URL | None = None,
281288
timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN,
282289
max_retries: int = DEFAULT_MAX_RETRIES,
@@ -298,15 +305,15 @@ def __init__(
298305
) -> None:
299306
"""Construct a new async AsyncReplicate client instance.
300307
301-
This automatically infers the `bearer_token` argument from the `REPLICATE_API_TOKEN` environment variable if it is not provided.
308+
This automatically infers the `api_key` argument from the `REPLICATE_CLIENT_API_KEY` environment variable if it is not provided.
302309
"""
303-
if bearer_token is None:
304-
bearer_token = os.environ.get("REPLICATE_API_TOKEN")
305-
if bearer_token is None:
310+
if api_key is None:
311+
api_key = os.environ.get("REPLICATE_CLIENT_API_KEY")
312+
if api_key is None:
306313
raise ReplicateError(
307-
"The bearer_token client option must be set either by passing bearer_token to the client or by setting the REPLICATE_API_TOKEN environment variable"
314+
"The api_key client option must be set either by passing api_key to the client or by setting the REPLICATE_CLIENT_API_KEY environment variable"
308315
)
309-
self.bearer_token = bearer_token
316+
self.api_key = api_key
310317

311318
if base_url is None:
312319
base_url = os.environ.get("REPLICATE_BASE_URL")
@@ -372,6 +379,12 @@ def webhooks(self) -> AsyncWebhooksResource:
372379

373380
return AsyncWebhooksResource(self)
374381

382+
@cached_property
383+
def files(self) -> AsyncFilesResource:
384+
from .resources.files import AsyncFilesResource
385+
386+
return AsyncFilesResource(self)
387+
375388
@cached_property
376389
def with_raw_response(self) -> AsyncReplicateWithRawResponse:
377390
return AsyncReplicateWithRawResponse(self)
@@ -388,8 +401,8 @@ def qs(self) -> Querystring:
388401
@property
389402
@override
390403
def auth_headers(self) -> dict[str, str]:
391-
bearer_token = self.bearer_token
392-
return {"Authorization": f"Bearer {bearer_token}"}
404+
api_key = self.api_key
405+
return {"Authorization": f"Bearer {api_key}"}
393406

394407
@property
395408
@override
@@ -403,7 +416,7 @@ def default_headers(self) -> dict[str, str | Omit]:
403416
def copy(
404417
self,
405418
*,
406-
bearer_token: str | None = None,
419+
api_key: str | None = None,
407420
base_url: str | httpx.URL | None = None,
408421
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
409422
http_client: httpx.AsyncClient | None = None,
@@ -437,7 +450,7 @@ def copy(
437450

438451
http_client = http_client or self._client
439452
return self.__class__(
440-
bearer_token=bearer_token or self.bearer_token,
453+
api_key=api_key or self.api_key,
441454
base_url=base_url or self.base_url,
442455
timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
443456
http_client=http_client,
@@ -539,6 +552,12 @@ def webhooks(self) -> webhooks.WebhooksResourceWithRawResponse:
539552

540553
return WebhooksResourceWithRawResponse(self._client.webhooks)
541554

555+
@cached_property
556+
def files(self) -> files.FilesResourceWithRawResponse:
557+
from .resources.files import FilesResourceWithRawResponse
558+
559+
return FilesResourceWithRawResponse(self._client.files)
560+
542561

543562
class AsyncReplicateWithRawResponse:
544563
_client: AsyncReplicate
@@ -594,6 +613,12 @@ def webhooks(self) -> webhooks.AsyncWebhooksResourceWithRawResponse:
594613

595614
return AsyncWebhooksResourceWithRawResponse(self._client.webhooks)
596615

616+
@cached_property
617+
def files(self) -> files.AsyncFilesResourceWithRawResponse:
618+
from .resources.files import AsyncFilesResourceWithRawResponse
619+
620+
return AsyncFilesResourceWithRawResponse(self._client.files)
621+
597622

598623
class ReplicateWithStreamedResponse:
599624
_client: Replicate
@@ -649,6 +674,12 @@ def webhooks(self) -> webhooks.WebhooksResourceWithStreamingResponse:
649674

650675
return WebhooksResourceWithStreamingResponse(self._client.webhooks)
651676

677+
@cached_property
678+
def files(self) -> files.FilesResourceWithStreamingResponse:
679+
from .resources.files import FilesResourceWithStreamingResponse
680+
681+
return FilesResourceWithStreamingResponse(self._client.files)
682+
652683

653684
class AsyncReplicateWithStreamedResponse:
654685
_client: AsyncReplicate
@@ -704,6 +735,12 @@ def webhooks(self) -> webhooks.AsyncWebhooksResourceWithStreamingResponse:
704735

705736
return AsyncWebhooksResourceWithStreamingResponse(self._client.webhooks)
706737

738+
@cached_property
739+
def files(self) -> files.AsyncFilesResourceWithStreamingResponse:
740+
from .resources.files import AsyncFilesResourceWithStreamingResponse
741+
742+
return AsyncFilesResourceWithStreamingResponse(self._client.files)
743+
707744

708745
Client = Replicate
709746

‎src/replicate/_files.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def assert_is_file_content(obj: object, *, key: str | None = None) -> None:
3434
if not is_file_content(obj):
3535
prefix = f"Expected entry at `{key}`" if key is not None else f"Expected file input `{obj!r}`"
3636
raise RuntimeError(
37-
f"{prefix} to be bytes, an io.IOBase instance, PathLike or a tuple but received {type(obj)} instead."
37+
f"{prefix} to be bytes, an io.IOBase instance, PathLike or a tuple but received {type(obj)} instead. See https://github.com/replicate/replicate-python-stainless/tree/main#file-uploads"
3838
) from None
3939

4040

‎src/replicate/_module_client.py‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from typing_extensions import override
77

88
if TYPE_CHECKING:
9+
from .resources.files import FilesResource
910
from .resources.account import AccountResource
1011
from .resources.hardware import HardwareResource
1112
from .resources.trainings import TrainingsResource
@@ -19,6 +20,12 @@
1920
from ._utils import LazyProxy
2021

2122

23+
class FilesResourceProxy(LazyProxy["FilesResource"]):
24+
@override
25+
def __load__(self) -> FilesResource:
26+
return _load_client().files
27+
28+
2229
class ModelsResourceProxy(LazyProxy["ModelsResource"]):
2330
@override
2431
def __load__(self) -> ModelsResource:
@@ -67,6 +74,7 @@ def __load__(self) -> PredictionsResource:
6774
return _load_client().predictions
6875

6976

77+
files: FilesResource = FilesResourceProxy().__as_proxied__()
7078
models: ModelsResource = ModelsResourceProxy().__as_proxied__()
7179
account: AccountResource = AccountResourceProxy().__as_proxied__()
7280
hardware: HardwareResource = HardwareResourceProxy().__as_proxied__()

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /