Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "2.0.0-alpha.25"
".": "2.0.0-alpha.26"
}
4 changes: 2 additions & 2 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 35
configured_endpoints: 36
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/replicate%2Freplicate-client-87c7c57bd75c54990c679c9e87d009851cdff572815a55d1b6ee4d4ee20adaa1.yml
openapi_spec_hash: d987f14befa536004eece7b49caad993
config_hash: b1b4f5d24ba07b4667ffe7b9dec081e3
config_hash: a916e7f3559ab312c7b6696cd6b35fb5
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# Changelog

## 2.0.0-alpha.26 (2025-09-17)

Full Changelog: [v2.0.0-alpha.25...v2.0.0-alpha.26](https://github.com/replicate/replicate-python-stainless/compare/v2.0.0-alpha.25...v2.0.0-alpha.26)

### Features

* **api:** add new replicate.search() method (beta) ([30d7019](https://github.com/replicate/replicate-python-stainless/commit/30d701999ea48ee65c5e5fd467072ccd5db35f87))


### Bug Fixes

* **tests:** fix tests for module-level client ([1e72f23](https://github.com/replicate/replicate-python-stainless/commit/1e72f23da3f0930955fe126848a8a8e58dbb710e))


### Chores

* **internal:** update pydantic dependency ([54872cb](https://github.com/replicate/replicate-python-stainless/commit/54872cb5e00fb65cae2abffcf0169a8b138e35fa))

## 2.0.0-alpha.25 (2025-09-15)

Full Changelog: [v2.0.0-alpha.24...v2.0.0-alpha.25](https://github.com/replicate/replicate-python-stainless/compare/v2.0.0-alpha.24...v2.0.0-alpha.25)
Expand Down
12 changes: 12 additions & 0 deletions api.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
# Replicate

Types:

```python
from replicate.types import SearchResponse
```

Methods:

- <code title="get /search">replicate.<a href="./src/replicate/_client.py">search</a>(\*\*<a href="src/replicate/types/client_search_params.py">params</a>) -> <a href="./src/replicate/types/search_response.py">SearchResponse</a></code>

# Collections

Types:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "replicate"
version = "2.0.0-alpha.25"
version = "2.0.0-alpha.26"
description = "The official Python library for the replicate API"
dynamic = ["readme"]
license = "Apache-2.0"
Expand Down
7 changes: 5 additions & 2 deletions requirements-dev.lock
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ pluggy==1.5.0
propcache==0.3.1
# via aiohttp
# via yarl
pydantic==2.10.3
pydantic==2.11.9
# via replicate
pydantic-core==2.27.1
pydantic-core==2.33.2
# via pydantic
pygments==2.18.0
# via rich
Expand Down Expand Up @@ -126,6 +126,9 @@ typing-extensions==4.12.2
# via pydantic-core
# via pyright
# via replicate
# via typing-inspection
typing-inspection==0.4.1
# via pydantic
virtualenv==20.24.5
# via nox
yarl==1.20.0
Expand Down
7 changes: 5 additions & 2 deletions requirements.lock
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ multidict==6.4.4
propcache==0.3.1
# via aiohttp
# via yarl
pydantic==2.10.3
pydantic==2.11.9
# via replicate
pydantic-core==2.27.1
pydantic-core==2.33.2
# via pydantic
sniffio==1.3.0
# via anyio
Expand All @@ -68,5 +68,8 @@ typing-extensions==4.12.2
# via pydantic
# via pydantic-core
# via replicate
# via typing-inspection
typing-inspection==0.4.1
# via pydantic
yarl==1.20.0
# via aiohttp
163 changes: 162 additions & 1 deletion src/replicate/_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,42 @@

from . import _exceptions
from ._qs import Querystring
from .types import client_search_params
from ._types import (
NOT_GIVEN,
Body,
Omit,
Query,
Headers,
Timeout,
NotGiven,
Transport,
ProxiesTypes,
RequestOptions,
)
from ._utils import is_given, get_async_library
from ._utils import (
is_given,
maybe_transform,
get_async_library,
async_maybe_transform,
)
from ._compat import cached_property
from ._version import __version__
from ._response import (
to_raw_response_wrapper,
to_streamed_response_wrapper,
async_to_raw_response_wrapper,
async_to_streamed_response_wrapper,
)
from ._streaming import Stream as Stream, AsyncStream as AsyncStream
from ._exceptions import APIStatusError, ReplicateError
from ._base_client import (
DEFAULT_MAX_RETRIES,
SyncAPIClient,
AsyncAPIClient,
make_request_options,
)
from .types.search_response import SearchResponse

if TYPE_CHECKING:
from .resources import files, models, account, hardware, webhooks, trainings, collections, deployments, predictions
Expand Down Expand Up @@ -354,6 +371,70 @@ def copy(
# client.with_options(timeout=10).foo.create(...)
with_options = copy

def search(
self,
*,
query: str,
limit: int | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> SearchResponse:
"""
Search for public models, collections, and docs using a text query.

For models, the response includes all model data, plus a new `metadata` object
with the following fields:

- `generated_description`: A longer and more detailed AI-generated description
of the model
- `tags`: An array of tags for the model
- `score`: A score for the model's relevance to the search query

Example cURL request:

```console
curl -s \\
-H "Authorization: Bearer $REPLICATE_API_TOKEN" \\
"https://api.replicate.com/v1/search?query=nano+banana"
```

Note: This search API is currently in beta and may change in future versions.

Args:
query: The search query string

limit: Maximum number of model results to return (1-50, defaults to 20)

extra_headers: Send extra headers

extra_query: Add additional query parameters to the request

extra_body: Add additional JSON properties to the request

timeout: Override the client-level default timeout for this request, in seconds
"""
return self.get(
"/search",
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
query=maybe_transform(
{
"query": query,
"limit": limit,
},
client_search_params.ClientSearchParams,
),
),
cast_to=SearchResponse,
)

@override
def _make_status_error(
self,
Expand Down Expand Up @@ -665,6 +746,70 @@ def copy(
# client.with_options(timeout=10).foo.create(...)
with_options = copy

async def search(
self,
*,
query: str,
limit: int | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> SearchResponse:
"""
Search for public models, collections, and docs using a text query.

For models, the response includes all model data, plus a new `metadata` object
with the following fields:

- `generated_description`: A longer and more detailed AI-generated description
of the model
- `tags`: An array of tags for the model
- `score`: A score for the model's relevance to the search query

Example cURL request:

```console
curl -s \\
-H "Authorization: Bearer $REPLICATE_API_TOKEN" \\
"https://api.replicate.com/v1/search?query=nano+banana"
```

Note: This search API is currently in beta and may change in future versions.

Args:
query: The search query string

limit: Maximum number of model results to return (1-50, defaults to 20)

extra_headers: Send extra headers

extra_query: Add additional query parameters to the request

extra_body: Add additional JSON properties to the request

timeout: Override the client-level default timeout for this request, in seconds
"""
return await self.get(
"/search",
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
query=await async_maybe_transform(
{
"query": query,
"limit": limit,
},
client_search_params.ClientSearchParams,
),
),
cast_to=SearchResponse,
)

@override
def _make_status_error(
self,
Expand Down Expand Up @@ -705,6 +850,10 @@ class ReplicateWithRawResponse:
def __init__(self, client: Replicate) -> None:
self._client = client

self.search = to_raw_response_wrapper(
client.search,
)

@cached_property
def collections(self) -> collections.CollectionsResourceWithRawResponse:
from .resources.collections import CollectionsResourceWithRawResponse
Expand Down Expand Up @@ -766,6 +915,10 @@ class AsyncReplicateWithRawResponse:
def __init__(self, client: AsyncReplicate) -> None:
self._client = client

self.search = async_to_raw_response_wrapper(
client.search,
)

@cached_property
def collections(self) -> collections.AsyncCollectionsResourceWithRawResponse:
from .resources.collections import AsyncCollectionsResourceWithRawResponse
Expand Down Expand Up @@ -827,6 +980,10 @@ class ReplicateWithStreamedResponse:
def __init__(self, client: Replicate) -> None:
self._client = client

self.search = to_streamed_response_wrapper(
client.search,
)

@cached_property
def collections(self) -> collections.CollectionsResourceWithStreamingResponse:
from .resources.collections import CollectionsResourceWithStreamingResponse
Expand Down Expand Up @@ -888,6 +1045,10 @@ class AsyncReplicateWithStreamedResponse:
def __init__(self, client: AsyncReplicate) -> None:
self._client = client

self.search = async_to_streamed_response_wrapper(
client.search,
)

@cached_property
def collections(self) -> collections.AsyncCollectionsResourceWithStreamingResponse:
from .resources.collections import AsyncCollectionsResourceWithStreamingResponse
Expand Down
14 changes: 10 additions & 4 deletions src/replicate/_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,14 +256,15 @@ def model_dump(
mode: Literal["json", "python"] | str = "python",
include: IncEx | None = None,
exclude: IncEx | None = None,
by_alias: bool = False,
by_alias: bool | None = None,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
round_trip: bool = False,
warnings: bool | Literal["none", "warn", "error"] = True,
context: dict[str, Any] | None = None,
serialize_as_any: bool = False,
fallback: Callable[[Any], Any] | None = None,
) -> dict[str, Any]:
"""Usage docs: https://docs.pydantic.dev/2.4/concepts/serialization/#modelmodel_dump

Expand Down Expand Up @@ -295,10 +296,12 @@ def model_dump(
raise ValueError("context is only supported in Pydantic v2")
if serialize_as_any != False:
raise ValueError("serialize_as_any is only supported in Pydantic v2")
if fallback is not None:
raise ValueError("fallback is only supported in Pydantic v2")
dumped = super().dict( # pyright: ignore[reportDeprecated]
include=include,
exclude=exclude,
by_alias=by_alias,
by_alias=by_alias if by_alias is not None else False,
exclude_unset=exclude_unset,
exclude_defaults=exclude_defaults,
exclude_none=exclude_none,
Expand All @@ -313,13 +316,14 @@ def model_dump_json(
indent: int | None = None,
include: IncEx | None = None,
exclude: IncEx | None = None,
by_alias: bool = False,
by_alias: bool | None = None,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
round_trip: bool = False,
warnings: bool | Literal["none", "warn", "error"] = True,
context: dict[str, Any] | None = None,
fallback: Callable[[Any], Any] | None = None,
serialize_as_any: bool = False,
) -> str:
"""Usage docs: https://docs.pydantic.dev/2.4/concepts/serialization/#modelmodel_dump_json
Expand Down Expand Up @@ -348,11 +352,13 @@ def model_dump_json(
raise ValueError("context is only supported in Pydantic v2")
if serialize_as_any != False:
raise ValueError("serialize_as_any is only supported in Pydantic v2")
if fallback is not None:
raise ValueError("fallback is only supported in Pydantic v2")
return super().json( # type: ignore[reportDeprecated]
indent=indent,
include=include,
exclude=exclude,
by_alias=by_alias,
by_alias=by_alias if by_alias is not None else False,
exclude_unset=exclude_unset,
exclude_defaults=exclude_defaults,
exclude_none=exclude_none,
Expand Down
Loading