From 40597d61653f176b02ba776cb15229a369891cf9 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 25 Jun 2025 13:28:23 +0000 Subject: [PATCH 1/3] feat(api): update via SDK Studio --- .stats.yml | 2 +- README.md | 63 +++++++++++++++++ api.md | 23 +++---- src/mixedbread/pagination.py | 67 ++++++++++++++++++- .../resources/data_sources/connectors.py | 22 +++--- .../resources/data_sources/data_sources.py | 22 +++--- src/mixedbread/resources/files.py | 22 +++--- src/mixedbread/resources/parsing/jobs.py | 21 +++--- .../resources/vector_stores/files.py | 22 +++--- .../resources/vector_stores/vector_stores.py | 22 +++--- src/mixedbread/types/__init__.py | 3 - .../types/data_source_list_response.py | 37 ---------- src/mixedbread/types/data_sources/__init__.py | 1 - .../data_sources/connector_list_response.py | 37 ---------- src/mixedbread/types/file_list_response.py | 37 ---------- .../types/parsing/job_list_response.py | 34 +--------- .../types/vector_store_list_response.py | 37 ---------- .../types/vector_stores/__init__.py | 1 - .../types/vector_stores/file_list_response.py | 37 ---------- .../data_sources/test_connectors.py | 18 ++--- tests/api_resources/parsing/test_jobs.py | 17 ++--- tests/api_resources/test_data_sources.py | 18 ++--- tests/api_resources/test_files.py | 23 +++---- tests/api_resources/test_vector_stores.py | 18 ++--- .../api_resources/vector_stores/test_files.py | 18 ++--- 25 files changed, 268 insertions(+), 354 deletions(-) delete mode 100644 src/mixedbread/types/data_source_list_response.py delete mode 100644 src/mixedbread/types/data_sources/connector_list_response.py delete mode 100644 src/mixedbread/types/file_list_response.py delete mode 100644 src/mixedbread/types/vector_store_list_response.py delete mode 100644 src/mixedbread/types/vector_stores/file_list_response.py diff --git a/.stats.yml b/.stats.yml index 5cdcb68a..8c28e2d6 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 49 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/mixedbread%2Fmixedbread-fd1562786a889e981d7d9b30d7f4b29d3d2ea11a8c30e19b919fae07ea355ccd.yml openapi_spec_hash: 1d83645e7d7bc1b6ccfc1ecc7cca656a -config_hash: ca0dfb431a44ea42464c42b224addf36 +config_hash: a36f4234467ae4cd0bea12552fcaaa4e diff --git a/README.md b/README.md index 8bfd5cf1..d4ec35ba 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,69 @@ Nested request parameters are [TypedDicts](https://docs.python.org/3/library/typ Typed requests and responses provide autocomplete and documentation within your editor. If you would like to see type errors in VS Code to help catch bugs earlier, set `python.analysis.typeCheckingMode` to `basic`. +## Pagination + +List methods in the Mixedbread API are paginated. + +This library provides auto-paginating iterators with each list response, so you do not have to request successive pages manually: + +```python +from mixedbread import Mixedbread + +client = Mixedbread() + +all_vector_stores = [] +# Automatically fetches more pages as needed. +for vector_store in client.vector_stores.list(): + # Do something with vector_store here + all_vector_stores.append(vector_store) +print(all_vector_stores) +``` + +Or, asynchronously: + +```python +import asyncio +from mixedbread import AsyncMixedbread + +client = AsyncMixedbread() + + +async def main() -> None: + all_vector_stores = [] + # Iterate through items across all pages, issuing requests as needed. + async for vector_store in client.vector_stores.list(): + all_vector_stores.append(vector_store) + print(all_vector_stores) + + +asyncio.run(main()) +``` + +Alternatively, you can use the `.has_next_page()`, `.next_page_info()`, or `.get_next_page()` methods for more granular control working with pages: + +```python +first_page = await client.vector_stores.list() +if first_page.has_next_page(): + print(f"will fetch next page using these details: {first_page.next_page_info()}") + next_page = await first_page.get_next_page() + print(f"number of items we just fetched: {len(next_page.data)}") + +# Remove `await` for non-async usage. +``` + +Or just work directly with the returned data: + +```python +first_page = await client.vector_stores.list() + +print(f"next page cursor: {first_page.pagination.next_cursor}") # => "next page cursor: ..." +for vector_store in first_page.data: + print(vector_store.id) + +# Remove `await` for non-async usage. +``` + ## Nested params Nested parameters are dictionaries, typed using `TypedDict`, for example: diff --git a/api.md b/api.md index 71c47d0b..a9f5376f 100644 --- a/api.md +++ b/api.md @@ -37,7 +37,6 @@ from mixedbread.types import ( ScoredVideoURLInputChunk, VectorStore, VectorStoreChunkSearchOptions, - VectorStoreListResponse, VectorStoreDeleteResponse, VectorStoreQuestionAnsweringResponse, VectorStoreSearchResponse, @@ -49,7 +48,7 @@ Methods: - client.vector_stores.create(\*\*params) -> VectorStore - client.vector_stores.retrieve(vector_store_identifier) -> VectorStore - client.vector_stores.update(vector_store_identifier, \*\*params) -> VectorStore -- client.vector_stores.list(\*\*params) -> VectorStoreListResponse +- client.vector_stores.list(\*\*params) -> SyncCursor[VectorStore] - client.vector_stores.delete(vector_store_identifier) -> VectorStoreDeleteResponse - client.vector_stores.question_answering(\*\*params) -> VectorStoreQuestionAnsweringResponse - client.vector_stores.search(\*\*params) -> VectorStoreSearchResponse @@ -64,7 +63,6 @@ from mixedbread.types.vector_stores import ( ScoredVectorStoreFile, VectorStoreFileStatus, VectorStoreFile, - FileListResponse, FileDeleteResponse, FileSearchResponse, ) @@ -74,7 +72,7 @@ Methods: - client.vector_stores.files.create(vector_store_identifier, \*\*params) -> VectorStoreFile - client.vector_stores.files.retrieve(file_id, \*, vector_store_identifier) -> VectorStoreFile -- client.vector_stores.files.list(vector_store_identifier, \*\*params) -> FileListResponse +- client.vector_stores.files.list(vector_store_identifier, \*\*params) -> SyncCursor[VectorStoreFile] - client.vector_stores.files.delete(file_id, \*, vector_store_identifier) -> FileDeleteResponse - client.vector_stores.files.search(\*\*params) -> FileSearchResponse @@ -100,7 +98,7 @@ Methods: - client.parsing.jobs.create(\*\*params) -> ParsingJob - client.parsing.jobs.retrieve(job_id) -> ParsingJob -- client.parsing.jobs.list(\*\*params) -> JobListResponse +- client.parsing.jobs.list(\*\*params) -> SyncCursor[JobListResponse] - client.parsing.jobs.delete(job_id) -> JobDeleteResponse - client.parsing.jobs.cancel(job_id) -> ParsingJob @@ -109,7 +107,7 @@ Methods: Types: ```python -from mixedbread.types import FileObject, PaginationWithTotal, FileListResponse, FileDeleteResponse +from mixedbread.types import FileObject, PaginationWithTotal, FileDeleteResponse ``` Methods: @@ -117,7 +115,7 @@ Methods: - client.files.create(\*\*params) -> FileObject - client.files.retrieve(file_id) -> FileObject - client.files.update(file_id, \*\*params) -> FileObject -- client.files.list(\*\*params) -> FileListResponse +- client.files.list(\*\*params) -> SyncCursor[FileObject] - client.files.delete(file_id) -> FileDeleteResponse - client.files.content(file_id) -> BinaryAPIResponse @@ -186,7 +184,6 @@ from mixedbread.types import ( LinearDataSource, NotionDataSource, Oauth2Params, - DataSourceListResponse, DataSourceDeleteResponse, ) ``` @@ -196,7 +193,7 @@ Methods: - client.data_sources.create(\*\*params) -> DataSource - client.data_sources.retrieve(data_source_id) -> DataSource - client.data_sources.update(data_source_id, \*\*params) -> DataSource -- client.data_sources.list(\*\*params) -> DataSourceListResponse +- client.data_sources.list(\*\*params) -> SyncCursor[DataSource] - client.data_sources.delete(data_source_id) -> DataSourceDeleteResponse ## Connectors @@ -204,11 +201,7 @@ Methods: Types: ```python -from mixedbread.types.data_sources import ( - DataSourceConnector, - ConnectorListResponse, - ConnectorDeleteResponse, -) +from mixedbread.types.data_sources import DataSourceConnector, ConnectorDeleteResponse ``` Methods: @@ -216,7 +209,7 @@ Methods: - client.data_sources.connectors.create(data_source_id, \*\*params) -> DataSourceConnector - client.data_sources.connectors.retrieve(connector_id, \*, data_source_id) -> DataSourceConnector - client.data_sources.connectors.update(connector_id, \*, data_source_id, \*\*params) -> DataSourceConnector -- client.data_sources.connectors.list(data_source_id, \*\*params) -> ConnectorListResponse +- client.data_sources.connectors.list(data_source_id, \*\*params) -> SyncCursor[DataSourceConnector] - client.data_sources.connectors.delete(connector_id, \*, data_source_id) -> ConnectorDeleteResponse # APIKeys diff --git a/src/mixedbread/pagination.py b/src/mixedbread/pagination.py index c2f1ea59..581f4f65 100644 --- a/src/mixedbread/pagination.py +++ b/src/mixedbread/pagination.py @@ -6,7 +6,14 @@ from ._models import BaseModel from ._base_client import BasePage, PageInfo, BaseSyncPage, BaseAsyncPage -__all__ = ["LimitOffsetPagination", "SyncLimitOffset", "AsyncLimitOffset"] +__all__ = [ + "LimitOffsetPagination", + "SyncLimitOffset", + "AsyncLimitOffset", + "CursorPagination", + "SyncCursor", + "AsyncCursor", +] _T = TypeVar("_T") @@ -87,3 +94,61 @@ def next_page_info(self) -> Optional[PageInfo]: return PageInfo(params={"offset": current_count}) return None + + +class CursorPagination(BaseModel): + next_cursor: Optional[str] = None + + prev_cursor: Optional[str] = None + + has_more: Optional[object] = None + + has_prev: Optional[bool] = None + + total: Optional[int] = None + + +class SyncCursor(BaseSyncPage[_T], BasePage[_T], Generic[_T]): + data: List[_T] + pagination: Optional[CursorPagination] = None + + @override + def _get_page_items(self) -> List[_T]: + data = self.data + if not data: + return [] + return data + + @override + def next_page_info(self) -> Optional[PageInfo]: + next_cursor = None + if self.pagination is not None: + if self.pagination.next_cursor is not None: + next_cursor = self.pagination.next_cursor + if not next_cursor: + return None + + return PageInfo(params={"cursor": next_cursor}) + + +class AsyncCursor(BaseAsyncPage[_T], BasePage[_T], Generic[_T]): + data: List[_T] + pagination: Optional[CursorPagination] = None + + @override + def _get_page_items(self) -> List[_T]: + data = self.data + if not data: + return [] + return data + + @override + def next_page_info(self) -> Optional[PageInfo]: + next_cursor = None + if self.pagination is not None: + if self.pagination.next_cursor is not None: + next_cursor = self.pagination.next_cursor + if not next_cursor: + return None + + return PageInfo(params={"cursor": next_cursor}) diff --git a/src/mixedbread/resources/data_sources/connectors.py b/src/mixedbread/resources/data_sources/connectors.py index fd110748..dbc11701 100644 --- a/src/mixedbread/resources/data_sources/connectors.py +++ b/src/mixedbread/resources/data_sources/connectors.py @@ -16,10 +16,10 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) -from ..._base_client import make_request_options +from ...pagination import SyncCursor, AsyncCursor +from ..._base_client import AsyncPaginator, make_request_options from ...types.data_sources import connector_list_params, connector_create_params, connector_update_params from ...types.data_sources.data_source_connector import DataSourceConnector -from ...types.data_sources.connector_list_response import ConnectorListResponse from ...types.data_sources.connector_delete_response import ConnectorDeleteResponse __all__ = ["ConnectorsResource", "AsyncConnectorsResource"] @@ -245,7 +245,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> ConnectorListResponse: + ) -> SyncCursor[DataSourceConnector]: """ Get all connectors for a data source. @@ -273,8 +273,9 @@ def list( """ if not data_source_id: raise ValueError(f"Expected a non-empty value for `data_source_id` but received {data_source_id!r}") - return self._get( + return self._get_api_list( f"/v1/data_sources/{data_source_id}/connectors", + page=SyncCursor[DataSourceConnector], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -289,7 +290,7 @@ def list( connector_list_params.ConnectorListParams, ), ), - cast_to=ConnectorListResponse, + model=DataSourceConnector, ) def delete( @@ -545,7 +546,7 @@ async def update( cast_to=DataSourceConnector, ) - async def list( + def list( self, data_source_id: str, *, @@ -558,7 +559,7 @@ async def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> ConnectorListResponse: + ) -> AsyncPaginator[DataSourceConnector, AsyncCursor[DataSourceConnector]]: """ Get all connectors for a data source. @@ -586,14 +587,15 @@ async def list( """ if not data_source_id: raise ValueError(f"Expected a non-empty value for `data_source_id` but received {data_source_id!r}") - return await self._get( + return self._get_api_list( f"/v1/data_sources/{data_source_id}/connectors", + page=AsyncCursor[DataSourceConnector], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "limit": limit, "cursor": cursor, @@ -602,7 +604,7 @@ async def list( connector_list_params.ConnectorListParams, ), ), - cast_to=ConnectorListResponse, + model=DataSourceConnector, ) async def delete( diff --git a/src/mixedbread/resources/data_sources/data_sources.py b/src/mixedbread/resources/data_sources/data_sources.py index d82939db..d9e4920f 100644 --- a/src/mixedbread/resources/data_sources/data_sources.py +++ b/src/mixedbread/resources/data_sources/data_sources.py @@ -32,11 +32,11 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) -from ..._base_client import make_request_options +from ...pagination import SyncCursor, AsyncCursor +from ..._base_client import AsyncPaginator, make_request_options from ...types.data_source import DataSource from ...types.oauth2_params import Oauth2Params from ...types.data_source_type import DataSourceType -from ...types.data_source_list_response import DataSourceListResponse from ...types.data_source_delete_response import DataSourceDeleteResponse __all__ = ["DataSourcesResource", "AsyncDataSourcesResource"] @@ -364,7 +364,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> DataSourceListResponse: + ) -> SyncCursor[DataSource]: """ Get all data sources. @@ -385,8 +385,9 @@ def list( timeout: Override the client-level default timeout for this request, in seconds """ - return self._get( + return self._get_api_list( "/v1/data_sources/", + page=SyncCursor[DataSource], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -401,7 +402,7 @@ def list( data_source_list_params.DataSourceListParams, ), ), - cast_to=DataSourceListResponse, + model=DataSource, ) def delete( @@ -752,7 +753,7 @@ async def update( cast_to=DataSource, ) - async def list( + def list( self, *, limit: int | NotGiven = NOT_GIVEN, @@ -764,7 +765,7 @@ async def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> DataSourceListResponse: + ) -> AsyncPaginator[DataSource, AsyncCursor[DataSource]]: """ Get all data sources. @@ -785,14 +786,15 @@ async def list( timeout: Override the client-level default timeout for this request, in seconds """ - return await self._get( + return self._get_api_list( "/v1/data_sources/", + page=AsyncCursor[DataSource], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "limit": limit, "cursor": cursor, @@ -801,7 +803,7 @@ async def list( data_source_list_params.DataSourceListParams, ), ), - cast_to=DataSourceListResponse, + model=DataSource, ) async def delete( diff --git a/src/mixedbread/resources/files.py b/src/mixedbread/resources/files.py index 207336ac..f02646cb 100644 --- a/src/mixedbread/resources/files.py +++ b/src/mixedbread/resources/files.py @@ -25,9 +25,9 @@ async_to_custom_raw_response_wrapper, async_to_custom_streamed_response_wrapper, ) -from .._base_client import make_request_options +from ..pagination import SyncCursor, AsyncCursor +from .._base_client import AsyncPaginator, make_request_options from ..types.file_object import FileObject -from ..types.file_list_response import FileListResponse from ..types.file_delete_response import FileDeleteResponse __all__ = ["FilesResource", "AsyncFilesResource"] @@ -199,7 +199,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> FileListResponse: + ) -> SyncCursor[FileObject]: """ List all files for the authenticated user. @@ -222,8 +222,9 @@ def list( timeout: Override the client-level default timeout for this request, in seconds """ - return self._get( + return self._get_api_list( "/v1/files", + page=SyncCursor[FileObject], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -238,7 +239,7 @@ def list( file_list_params.FileListParams, ), ), - cast_to=FileListResponse, + model=FileObject, ) def delete( @@ -475,7 +476,7 @@ async def update( cast_to=FileObject, ) - async def list( + def list( self, *, limit: int | NotGiven = NOT_GIVEN, @@ -487,7 +488,7 @@ async def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> FileListResponse: + ) -> AsyncPaginator[FileObject, AsyncCursor[FileObject]]: """ List all files for the authenticated user. @@ -510,14 +511,15 @@ async def list( timeout: Override the client-level default timeout for this request, in seconds """ - return await self._get( + return self._get_api_list( "/v1/files", + page=AsyncCursor[FileObject], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "limit": limit, "cursor": cursor, @@ -526,7 +528,7 @@ async def list( file_list_params.FileListParams, ), ), - cast_to=FileListResponse, + model=FileObject, ) async def delete( diff --git a/src/mixedbread/resources/parsing/jobs.py b/src/mixedbread/resources/parsing/jobs.py index 1cbe0b7a..1d458ae7 100644 --- a/src/mixedbread/resources/parsing/jobs.py +++ b/src/mixedbread/resources/parsing/jobs.py @@ -19,7 +19,8 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) -from ..._base_client import make_request_options +from ...pagination import SyncCursor, AsyncCursor +from ..._base_client import AsyncPaginator, make_request_options from ...types.parsing import ReturnFormat, ChunkingStrategy, job_list_params, job_create_params from ...types.parsing.parsing_job import ParsingJob from ...types.parsing.element_type import ElementType @@ -161,7 +162,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> JobListResponse: + ) -> SyncCursor[JobListResponse]: """List parsing jobs with pagination. Args: limit: The number of items to return. @@ -185,8 +186,9 @@ def list( timeout: Override the client-level default timeout for this request, in seconds """ - return self._get( + return self._get_api_list( "/v1/parsing/jobs", + page=SyncCursor[JobListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -201,7 +203,7 @@ def list( job_list_params.JobListParams, ), ), - cast_to=JobListResponse, + model=JobListResponse, ) def delete( @@ -558,7 +560,7 @@ async def retrieve( cast_to=ParsingJob, ) - async def list( + def list( self, *, limit: int | NotGiven = NOT_GIVEN, @@ -570,7 +572,7 @@ async def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> JobListResponse: + ) -> AsyncPaginator[JobListResponse, AsyncCursor[JobListResponse]]: """List parsing jobs with pagination. Args: limit: The number of items to return. @@ -594,14 +596,15 @@ async def list( timeout: Override the client-level default timeout for this request, in seconds """ - return await self._get( + return self._get_api_list( "/v1/parsing/jobs", + page=AsyncCursor[JobListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "limit": limit, "cursor": cursor, @@ -610,7 +613,7 @@ async def list( job_list_params.JobListParams, ), ), - cast_to=JobListResponse, + model=JobListResponse, ) async def delete( diff --git a/src/mixedbread/resources/vector_stores/files.py b/src/mixedbread/resources/vector_stores/files.py index b84f574f..189660a1 100644 --- a/src/mixedbread/resources/vector_stores/files.py +++ b/src/mixedbread/resources/vector_stores/files.py @@ -18,10 +18,10 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) -from ..._base_client import make_request_options +from ...pagination import SyncCursor, AsyncCursor +from ..._base_client import AsyncPaginator, make_request_options from ...types.vector_stores import file_list_params, file_create_params, file_search_params from ...types.vector_stores.vector_store_file import VectorStoreFile -from ...types.vector_stores.file_list_response import FileListResponse from ...types.vector_stores.file_delete_response import FileDeleteResponse from ...types.vector_stores.file_search_response import FileSearchResponse from ...types.vector_stores.vector_store_file_status import VectorStoreFileStatus @@ -169,7 +169,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> FileListResponse: + ) -> SyncCursor[VectorStoreFile]: """ List files indexed in a vector store with pagination. @@ -201,8 +201,9 @@ def list( raise ValueError( f"Expected a non-empty value for `vector_store_identifier` but received {vector_store_identifier!r}" ) - return self._get( + return self._get_api_list( f"/v1/vector_stores/{vector_store_identifier}/files", + page=SyncCursor[VectorStoreFile], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -218,7 +219,7 @@ def list( file_list_params.FileListParams, ), ), - cast_to=FileListResponse, + model=VectorStoreFile, ) def delete( @@ -577,7 +578,7 @@ async def retrieve( cast_to=VectorStoreFile, ) - async def list( + def list( self, vector_store_identifier: str, *, @@ -591,7 +592,7 @@ async def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> FileListResponse: + ) -> AsyncPaginator[VectorStoreFile, AsyncCursor[VectorStoreFile]]: """ List files indexed in a vector store with pagination. @@ -623,14 +624,15 @@ async def list( raise ValueError( f"Expected a non-empty value for `vector_store_identifier` but received {vector_store_identifier!r}" ) - return await self._get( + return self._get_api_list( f"/v1/vector_stores/{vector_store_identifier}/files", + page=AsyncCursor[VectorStoreFile], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "limit": limit, "cursor": cursor, @@ -640,7 +642,7 @@ async def list( file_list_params.FileListParams, ), ), - cast_to=FileListResponse, + model=VectorStoreFile, ) async def delete( diff --git a/src/mixedbread/resources/vector_stores/vector_stores.py b/src/mixedbread/resources/vector_stores/vector_stores.py index 21f559df..768923bf 100644 --- a/src/mixedbread/resources/vector_stores/vector_stores.py +++ b/src/mixedbread/resources/vector_stores/vector_stores.py @@ -31,10 +31,10 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) -from ..._base_client import make_request_options +from ...pagination import SyncCursor, AsyncCursor +from ..._base_client import AsyncPaginator, make_request_options from ...types.vector_store import VectorStore from ...types.expires_after_param import ExpiresAfterParam -from ...types.vector_store_list_response import VectorStoreListResponse from ...types.vector_store_delete_response import VectorStoreDeleteResponse from ...types.vector_store_search_response import VectorStoreSearchResponse from ...types.vector_store_chunk_search_options_param import VectorStoreChunkSearchOptionsParam @@ -253,7 +253,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> VectorStoreListResponse: + ) -> SyncCursor[VectorStore]: """ List all vector stores with optional search. @@ -279,8 +279,9 @@ def list( timeout: Override the client-level default timeout for this request, in seconds """ - return self._get( + return self._get_api_list( "/v1/vector_stores", + page=SyncCursor[VectorStore], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -296,7 +297,7 @@ def list( vector_store_list_params.VectorStoreListParams, ), ), - cast_to=VectorStoreListResponse, + model=VectorStore, ) def delete( @@ -686,7 +687,7 @@ async def update( cast_to=VectorStore, ) - async def list( + def list( self, *, limit: int | NotGiven = NOT_GIVEN, @@ -699,7 +700,7 @@ async def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> VectorStoreListResponse: + ) -> AsyncPaginator[VectorStore, AsyncCursor[VectorStore]]: """ List all vector stores with optional search. @@ -725,14 +726,15 @@ async def list( timeout: Override the client-level default timeout for this request, in seconds """ - return await self._get( + return self._get_api_list( "/v1/vector_stores", + page=AsyncCursor[VectorStore], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "limit": limit, "cursor": cursor, @@ -742,7 +744,7 @@ async def list( vector_store_list_params.VectorStoreListParams, ), ), - cast_to=VectorStoreListResponse, + model=VectorStore, ) async def delete( diff --git a/src/mixedbread/types/__init__.py b/src/mixedbread/types/__init__.py index a726eb8f..5fead10f 100644 --- a/src/mixedbread/types/__init__.py +++ b/src/mixedbread/types/__init__.py @@ -18,7 +18,6 @@ from .data_source_type import DataSourceType as DataSourceType from .file_list_params import FileListParams as FileListParams from .file_create_params import FileCreateParams as FileCreateParams -from .file_list_response import FileListResponse as FileListResponse from .file_update_params import FileUpdateParams as FileUpdateParams from .api_key_list_params import APIKeyListParams as APIKeyListParams from .client_embed_params import ClientEmbedParams as ClientEmbedParams @@ -36,12 +35,10 @@ from .notion_data_source_param import NotionDataSourceParam as NotionDataSourceParam from .vector_store_list_params import VectorStoreListParams as VectorStoreListParams from .data_source_create_params import DataSourceCreateParams as DataSourceCreateParams -from .data_source_list_response import DataSourceListResponse as DataSourceListResponse from .data_source_oauth2_params import DataSourceOauth2Params as DataSourceOauth2Params from .data_source_update_params import DataSourceUpdateParams as DataSourceUpdateParams from .embedding_create_response import EmbeddingCreateResponse as EmbeddingCreateResponse from .vector_store_create_params import VectorStoreCreateParams as VectorStoreCreateParams -from .vector_store_list_response import VectorStoreListResponse as VectorStoreListResponse from .vector_store_search_params import VectorStoreSearchParams as VectorStoreSearchParams from .vector_store_update_params import VectorStoreUpdateParams as VectorStoreUpdateParams from .data_source_delete_response import DataSourceDeleteResponse as DataSourceDeleteResponse diff --git a/src/mixedbread/types/data_source_list_response.py b/src/mixedbread/types/data_source_list_response.py deleted file mode 100644 index 4c95ef7a..00000000 --- a/src/mixedbread/types/data_source_list_response.py +++ /dev/null @@ -1,37 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from typing_extensions import Literal - -from .._models import BaseModel -from .data_source import DataSource - -__all__ = ["DataSourceListResponse", "Pagination"] - - -class Pagination(BaseModel): - next_cursor: Optional[str] = None - """Cursor for the next page, null if no more pages""" - - prev_cursor: Optional[str] = None - """Cursor for the previous page, null if no previous pages""" - - has_more: bool - """Whether there are more items available""" - - has_prev: bool - """Whether there are previous items available""" - - total: Optional[int] = None - """Total number of items available""" - - -class DataSourceListResponse(BaseModel): - pagination: Pagination - """Response model for cursor-based pagination.""" - - data: List[DataSource] - """The list of data sources""" - - object: Optional[Literal["list"]] = None - """The object type of the response""" diff --git a/src/mixedbread/types/data_sources/__init__.py b/src/mixedbread/types/data_sources/__init__.py index c925bcc7..c35b6f2e 100644 --- a/src/mixedbread/types/data_sources/__init__.py +++ b/src/mixedbread/types/data_sources/__init__.py @@ -5,6 +5,5 @@ from .connector_list_params import ConnectorListParams as ConnectorListParams from .data_source_connector import DataSourceConnector as DataSourceConnector from .connector_create_params import ConnectorCreateParams as ConnectorCreateParams -from .connector_list_response import ConnectorListResponse as ConnectorListResponse from .connector_update_params import ConnectorUpdateParams as ConnectorUpdateParams from .connector_delete_response import ConnectorDeleteResponse as ConnectorDeleteResponse diff --git a/src/mixedbread/types/data_sources/connector_list_response.py b/src/mixedbread/types/data_sources/connector_list_response.py deleted file mode 100644 index e63cf824..00000000 --- a/src/mixedbread/types/data_sources/connector_list_response.py +++ /dev/null @@ -1,37 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from typing_extensions import Literal - -from ..._models import BaseModel -from .data_source_connector import DataSourceConnector - -__all__ = ["ConnectorListResponse", "Pagination"] - - -class Pagination(BaseModel): - next_cursor: Optional[str] = None - """Cursor for the next page, null if no more pages""" - - prev_cursor: Optional[str] = None - """Cursor for the previous page, null if no previous pages""" - - has_more: bool - """Whether there are more items available""" - - has_prev: bool - """Whether there are previous items available""" - - total: Optional[int] = None - """Total number of items available""" - - -class ConnectorListResponse(BaseModel): - pagination: Pagination - """Response model for cursor-based pagination.""" - - data: List[DataSourceConnector] - """The list of connectors""" - - object: Optional[Literal["list"]] = None - """The object type of the response""" diff --git a/src/mixedbread/types/file_list_response.py b/src/mixedbread/types/file_list_response.py deleted file mode 100644 index b66a56ad..00000000 --- a/src/mixedbread/types/file_list_response.py +++ /dev/null @@ -1,37 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from typing_extensions import Literal - -from .._models import BaseModel -from .file_object import FileObject - -__all__ = ["FileListResponse", "Pagination"] - - -class Pagination(BaseModel): - next_cursor: Optional[str] = None - """Cursor for the next page, null if no more pages""" - - prev_cursor: Optional[str] = None - """Cursor for the previous page, null if no previous pages""" - - has_more: bool - """Whether there are more items available""" - - has_prev: bool - """Whether there are previous items available""" - - total: Optional[int] = None - """Total number of items available""" - - -class FileListResponse(BaseModel): - pagination: Pagination - """Response model for cursor-based pagination.""" - - object: Optional[Literal["list"]] = None - """The object type of the response""" - - data: List[FileObject] - """The list of files""" diff --git a/src/mixedbread/types/parsing/job_list_response.py b/src/mixedbread/types/parsing/job_list_response.py index b0aea3f0..509d1620 100644 --- a/src/mixedbread/types/parsing/job_list_response.py +++ b/src/mixedbread/types/parsing/job_list_response.py @@ -1,33 +1,16 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import Optional from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel from .parsing_job_status import ParsingJobStatus -__all__ = ["JobListResponse", "Pagination", "Data"] +__all__ = ["JobListResponse"] -class Pagination(BaseModel): - next_cursor: Optional[str] = None - """Cursor for the next page, null if no more pages""" - - prev_cursor: Optional[str] = None - """Cursor for the previous page, null if no previous pages""" - - has_more: bool - """Whether there are more items available""" - - has_prev: bool - """Whether there are previous items available""" - - total: Optional[int] = None - """Total number of items available""" - - -class Data(BaseModel): +class JobListResponse(BaseModel): id: str """The ID of the job""" @@ -51,14 +34,3 @@ class Data(BaseModel): object: Optional[Literal["parsing_job"]] = None """The type of the object""" - - -class JobListResponse(BaseModel): - pagination: Pagination - """Response model for cursor-based pagination.""" - - data: List[Data] - """The list of parsing jobs""" - - object: Optional[Literal["list"]] = None - """The object type of the response""" diff --git a/src/mixedbread/types/vector_store_list_response.py b/src/mixedbread/types/vector_store_list_response.py deleted file mode 100644 index 54664f1a..00000000 --- a/src/mixedbread/types/vector_store_list_response.py +++ /dev/null @@ -1,37 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from typing_extensions import Literal - -from .._models import BaseModel -from .vector_store import VectorStore - -__all__ = ["VectorStoreListResponse", "Pagination"] - - -class Pagination(BaseModel): - next_cursor: Optional[str] = None - """Cursor for the next page, null if no more pages""" - - prev_cursor: Optional[str] = None - """Cursor for the previous page, null if no previous pages""" - - has_more: bool - """Whether there are more items available""" - - has_prev: bool - """Whether there are previous items available""" - - total: Optional[int] = None - """Total number of items available""" - - -class VectorStoreListResponse(BaseModel): - pagination: Pagination - """Response model for cursor-based pagination.""" - - object: Optional[Literal["list"]] = None - """The object type of the response""" - - data: List[VectorStore] - """The list of vector stores""" diff --git a/src/mixedbread/types/vector_stores/__init__.py b/src/mixedbread/types/vector_stores/__init__.py index f0cee6f2..6ce1aafe 100644 --- a/src/mixedbread/types/vector_stores/__init__.py +++ b/src/mixedbread/types/vector_stores/__init__.py @@ -5,7 +5,6 @@ from .file_list_params import FileListParams as FileListParams from .vector_store_file import VectorStoreFile as VectorStoreFile from .file_create_params import FileCreateParams as FileCreateParams -from .file_list_response import FileListResponse as FileListResponse from .file_search_params import FileSearchParams as FileSearchParams from .rerank_config_param import RerankConfigParam as RerankConfigParam from .file_delete_response import FileDeleteResponse as FileDeleteResponse diff --git a/src/mixedbread/types/vector_stores/file_list_response.py b/src/mixedbread/types/vector_stores/file_list_response.py deleted file mode 100644 index e566de6b..00000000 --- a/src/mixedbread/types/vector_stores/file_list_response.py +++ /dev/null @@ -1,37 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from typing_extensions import Literal - -from ..._models import BaseModel -from .vector_store_file import VectorStoreFile - -__all__ = ["FileListResponse", "Pagination"] - - -class Pagination(BaseModel): - next_cursor: Optional[str] = None - """Cursor for the next page, null if no more pages""" - - prev_cursor: Optional[str] = None - """Cursor for the previous page, null if no previous pages""" - - has_more: bool - """Whether there are more items available""" - - has_prev: bool - """Whether there are previous items available""" - - total: Optional[int] = None - """Total number of items available""" - - -class FileListResponse(BaseModel): - pagination: Pagination - """Response model for cursor-based pagination.""" - - object: Optional[Literal["list"]] = None - """The object type of the response""" - - data: List[VectorStoreFile] - """The list of vector store files""" diff --git a/tests/api_resources/data_sources/test_connectors.py b/tests/api_resources/data_sources/test_connectors.py index f32aeafb..352fed19 100644 --- a/tests/api_resources/data_sources/test_connectors.py +++ b/tests/api_resources/data_sources/test_connectors.py @@ -9,9 +9,9 @@ from mixedbread import Mixedbread, AsyncMixedbread from tests.utils import assert_matches_type +from mixedbread.pagination import SyncCursor, AsyncCursor from mixedbread.types.data_sources import ( DataSourceConnector, - ConnectorListResponse, ConnectorDeleteResponse, ) @@ -188,7 +188,7 @@ def test_method_list(self, client: Mixedbread) -> None: connector = client.data_sources.connectors.list( data_source_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) - assert_matches_type(ConnectorListResponse, connector, path=["response"]) + assert_matches_type(SyncCursor[DataSourceConnector], connector, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Mixedbread) -> None: @@ -198,7 +198,7 @@ def test_method_list_with_all_params(self, client: Mixedbread) -> None: cursor="cursor", include_total=True, ) - assert_matches_type(ConnectorListResponse, connector, path=["response"]) + assert_matches_type(SyncCursor[DataSourceConnector], connector, path=["response"]) @parametrize def test_raw_response_list(self, client: Mixedbread) -> None: @@ -209,7 +209,7 @@ def test_raw_response_list(self, client: Mixedbread) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" connector = response.parse() - assert_matches_type(ConnectorListResponse, connector, path=["response"]) + assert_matches_type(SyncCursor[DataSourceConnector], connector, path=["response"]) @parametrize def test_streaming_response_list(self, client: Mixedbread) -> None: @@ -220,7 +220,7 @@ def test_streaming_response_list(self, client: Mixedbread) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" connector = response.parse() - assert_matches_type(ConnectorListResponse, connector, path=["response"]) + assert_matches_type(SyncCursor[DataSourceConnector], connector, path=["response"]) assert cast(Any, response.is_closed) is True @@ -452,7 +452,7 @@ async def test_method_list(self, async_client: AsyncMixedbread) -> None: connector = await async_client.data_sources.connectors.list( data_source_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) - assert_matches_type(ConnectorListResponse, connector, path=["response"]) + assert_matches_type(AsyncCursor[DataSourceConnector], connector, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncMixedbread) -> None: @@ -462,7 +462,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncMixedbread) cursor="cursor", include_total=True, ) - assert_matches_type(ConnectorListResponse, connector, path=["response"]) + assert_matches_type(AsyncCursor[DataSourceConnector], connector, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncMixedbread) -> None: @@ -473,7 +473,7 @@ async def test_raw_response_list(self, async_client: AsyncMixedbread) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" connector = await response.parse() - assert_matches_type(ConnectorListResponse, connector, path=["response"]) + assert_matches_type(AsyncCursor[DataSourceConnector], connector, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncMixedbread) -> None: @@ -484,7 +484,7 @@ async def test_streaming_response_list(self, async_client: AsyncMixedbread) -> N assert response.http_request.headers.get("X-Stainless-Lang") == "python" connector = await response.parse() - assert_matches_type(ConnectorListResponse, connector, path=["response"]) + assert_matches_type(AsyncCursor[DataSourceConnector], connector, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/parsing/test_jobs.py b/tests/api_resources/parsing/test_jobs.py index 7b22a611..49f25077 100644 --- a/tests/api_resources/parsing/test_jobs.py +++ b/tests/api_resources/parsing/test_jobs.py @@ -9,6 +9,7 @@ from mixedbread import Mixedbread, AsyncMixedbread from tests.utils import assert_matches_type +from mixedbread.pagination import SyncCursor, AsyncCursor from mixedbread.types.parsing import ( ParsingJob, JobListResponse, @@ -104,7 +105,7 @@ def test_path_params_retrieve(self, client: Mixedbread) -> None: @parametrize def test_method_list(self, client: Mixedbread) -> None: job = client.parsing.jobs.list() - assert_matches_type(JobListResponse, job, path=["response"]) + assert_matches_type(SyncCursor[JobListResponse], job, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Mixedbread) -> None: @@ -113,7 +114,7 @@ def test_method_list_with_all_params(self, client: Mixedbread) -> None: cursor="cursor", include_total=True, ) - assert_matches_type(JobListResponse, job, path=["response"]) + assert_matches_type(SyncCursor[JobListResponse], job, path=["response"]) @parametrize def test_raw_response_list(self, client: Mixedbread) -> None: @@ -122,7 +123,7 @@ def test_raw_response_list(self, client: Mixedbread) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" job = response.parse() - assert_matches_type(JobListResponse, job, path=["response"]) + assert_matches_type(SyncCursor[JobListResponse], job, path=["response"]) @parametrize def test_streaming_response_list(self, client: Mixedbread) -> None: @@ -131,7 +132,7 @@ def test_streaming_response_list(self, client: Mixedbread) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" job = response.parse() - assert_matches_type(JobListResponse, job, path=["response"]) + assert_matches_type(SyncCursor[JobListResponse], job, path=["response"]) assert cast(Any, response.is_closed) is True @@ -300,7 +301,7 @@ async def test_path_params_retrieve(self, async_client: AsyncMixedbread) -> None @parametrize async def test_method_list(self, async_client: AsyncMixedbread) -> None: job = await async_client.parsing.jobs.list() - assert_matches_type(JobListResponse, job, path=["response"]) + assert_matches_type(AsyncCursor[JobListResponse], job, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncMixedbread) -> None: @@ -309,7 +310,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncMixedbread) cursor="cursor", include_total=True, ) - assert_matches_type(JobListResponse, job, path=["response"]) + assert_matches_type(AsyncCursor[JobListResponse], job, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncMixedbread) -> None: @@ -318,7 +319,7 @@ async def test_raw_response_list(self, async_client: AsyncMixedbread) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" job = await response.parse() - assert_matches_type(JobListResponse, job, path=["response"]) + assert_matches_type(AsyncCursor[JobListResponse], job, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncMixedbread) -> None: @@ -327,7 +328,7 @@ async def test_streaming_response_list(self, async_client: AsyncMixedbread) -> N assert response.http_request.headers.get("X-Stainless-Lang") == "python" job = await response.parse() - assert_matches_type(JobListResponse, job, path=["response"]) + assert_matches_type(AsyncCursor[JobListResponse], job, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_data_sources.py b/tests/api_resources/test_data_sources.py index 94ad5653..8c6cc68b 100644 --- a/tests/api_resources/test_data_sources.py +++ b/tests/api_resources/test_data_sources.py @@ -11,9 +11,9 @@ from tests.utils import assert_matches_type from mixedbread.types import ( DataSource, - DataSourceListResponse, DataSourceDeleteResponse, ) +from mixedbread.pagination import SyncCursor, AsyncCursor base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -250,7 +250,7 @@ def test_path_params_update_overload_2(self, client: Mixedbread) -> None: @parametrize def test_method_list(self, client: Mixedbread) -> None: data_source = client.data_sources.list() - assert_matches_type(DataSourceListResponse, data_source, path=["response"]) + assert_matches_type(SyncCursor[DataSource], data_source, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Mixedbread) -> None: @@ -259,7 +259,7 @@ def test_method_list_with_all_params(self, client: Mixedbread) -> None: cursor="cursor", include_total=True, ) - assert_matches_type(DataSourceListResponse, data_source, path=["response"]) + assert_matches_type(SyncCursor[DataSource], data_source, path=["response"]) @parametrize def test_raw_response_list(self, client: Mixedbread) -> None: @@ -268,7 +268,7 @@ def test_raw_response_list(self, client: Mixedbread) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" data_source = response.parse() - assert_matches_type(DataSourceListResponse, data_source, path=["response"]) + assert_matches_type(SyncCursor[DataSource], data_source, path=["response"]) @parametrize def test_streaming_response_list(self, client: Mixedbread) -> None: @@ -277,7 +277,7 @@ def test_streaming_response_list(self, client: Mixedbread) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" data_source = response.parse() - assert_matches_type(DataSourceListResponse, data_source, path=["response"]) + assert_matches_type(SyncCursor[DataSource], data_source, path=["response"]) assert cast(Any, response.is_closed) is True @@ -554,7 +554,7 @@ async def test_path_params_update_overload_2(self, async_client: AsyncMixedbread @parametrize async def test_method_list(self, async_client: AsyncMixedbread) -> None: data_source = await async_client.data_sources.list() - assert_matches_type(DataSourceListResponse, data_source, path=["response"]) + assert_matches_type(AsyncCursor[DataSource], data_source, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncMixedbread) -> None: @@ -563,7 +563,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncMixedbread) cursor="cursor", include_total=True, ) - assert_matches_type(DataSourceListResponse, data_source, path=["response"]) + assert_matches_type(AsyncCursor[DataSource], data_source, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncMixedbread) -> None: @@ -572,7 +572,7 @@ async def test_raw_response_list(self, async_client: AsyncMixedbread) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" data_source = await response.parse() - assert_matches_type(DataSourceListResponse, data_source, path=["response"]) + assert_matches_type(AsyncCursor[DataSource], data_source, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncMixedbread) -> None: @@ -581,7 +581,7 @@ async def test_streaming_response_list(self, async_client: AsyncMixedbread) -> N assert response.http_request.headers.get("X-Stainless-Lang") == "python" data_source = await response.parse() - assert_matches_type(DataSourceListResponse, data_source, path=["response"]) + assert_matches_type(AsyncCursor[DataSource], data_source, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_files.py b/tests/api_resources/test_files.py index 9fdc535d..51deafef 100644 --- a/tests/api_resources/test_files.py +++ b/tests/api_resources/test_files.py @@ -11,17 +11,14 @@ from mixedbread import Mixedbread, AsyncMixedbread from tests.utils import assert_matches_type -from mixedbread.types import ( - FileObject, - FileListResponse, - FileDeleteResponse, -) +from mixedbread.types import FileObject, FileDeleteResponse from mixedbread._response import ( BinaryAPIResponse, AsyncBinaryAPIResponse, StreamedBinaryAPIResponse, AsyncStreamedBinaryAPIResponse, ) +from mixedbread.pagination import SyncCursor, AsyncCursor base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -143,7 +140,7 @@ def test_path_params_update(self, client: Mixedbread) -> None: @parametrize def test_method_list(self, client: Mixedbread) -> None: file = client.files.list() - assert_matches_type(FileListResponse, file, path=["response"]) + assert_matches_type(SyncCursor[FileObject], file, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Mixedbread) -> None: @@ -152,7 +149,7 @@ def test_method_list_with_all_params(self, client: Mixedbread) -> None: cursor="cursor", include_total=True, ) - assert_matches_type(FileListResponse, file, path=["response"]) + assert_matches_type(SyncCursor[FileObject], file, path=["response"]) @parametrize def test_raw_response_list(self, client: Mixedbread) -> None: @@ -161,7 +158,7 @@ def test_raw_response_list(self, client: Mixedbread) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = response.parse() - assert_matches_type(FileListResponse, file, path=["response"]) + assert_matches_type(SyncCursor[FileObject], file, path=["response"]) @parametrize def test_streaming_response_list(self, client: Mixedbread) -> None: @@ -170,7 +167,7 @@ def test_streaming_response_list(self, client: Mixedbread) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = response.parse() - assert_matches_type(FileListResponse, file, path=["response"]) + assert_matches_type(SyncCursor[FileObject], file, path=["response"]) assert cast(Any, response.is_closed) is True @@ -388,7 +385,7 @@ async def test_path_params_update(self, async_client: AsyncMixedbread) -> None: @parametrize async def test_method_list(self, async_client: AsyncMixedbread) -> None: file = await async_client.files.list() - assert_matches_type(FileListResponse, file, path=["response"]) + assert_matches_type(AsyncCursor[FileObject], file, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncMixedbread) -> None: @@ -397,7 +394,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncMixedbread) cursor="cursor", include_total=True, ) - assert_matches_type(FileListResponse, file, path=["response"]) + assert_matches_type(AsyncCursor[FileObject], file, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncMixedbread) -> None: @@ -406,7 +403,7 @@ async def test_raw_response_list(self, async_client: AsyncMixedbread) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = await response.parse() - assert_matches_type(FileListResponse, file, path=["response"]) + assert_matches_type(AsyncCursor[FileObject], file, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncMixedbread) -> None: @@ -415,7 +412,7 @@ async def test_streaming_response_list(self, async_client: AsyncMixedbread) -> N assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = await response.parse() - assert_matches_type(FileListResponse, file, path=["response"]) + assert_matches_type(AsyncCursor[FileObject], file, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_vector_stores.py b/tests/api_resources/test_vector_stores.py index 4be0efcc..2fe4ab9f 100644 --- a/tests/api_resources/test_vector_stores.py +++ b/tests/api_resources/test_vector_stores.py @@ -11,11 +11,11 @@ from tests.utils import assert_matches_type from mixedbread.types import ( VectorStore, - VectorStoreListResponse, VectorStoreDeleteResponse, VectorStoreSearchResponse, VectorStoreQuestionAnsweringResponse, ) +from mixedbread.pagination import SyncCursor, AsyncCursor base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -161,7 +161,7 @@ def test_path_params_update(self, client: Mixedbread) -> None: @parametrize def test_method_list(self, client: Mixedbread) -> None: vector_store = client.vector_stores.list() - assert_matches_type(VectorStoreListResponse, vector_store, path=["response"]) + assert_matches_type(SyncCursor[VectorStore], vector_store, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Mixedbread) -> None: @@ -171,7 +171,7 @@ def test_method_list_with_all_params(self, client: Mixedbread) -> None: include_total=True, q="x", ) - assert_matches_type(VectorStoreListResponse, vector_store, path=["response"]) + assert_matches_type(SyncCursor[VectorStore], vector_store, path=["response"]) @parametrize def test_raw_response_list(self, client: Mixedbread) -> None: @@ -180,7 +180,7 @@ def test_raw_response_list(self, client: Mixedbread) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" vector_store = response.parse() - assert_matches_type(VectorStoreListResponse, vector_store, path=["response"]) + assert_matches_type(SyncCursor[VectorStore], vector_store, path=["response"]) @parametrize def test_streaming_response_list(self, client: Mixedbread) -> None: @@ -189,7 +189,7 @@ def test_streaming_response_list(self, client: Mixedbread) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" vector_store = response.parse() - assert_matches_type(VectorStoreListResponse, vector_store, path=["response"]) + assert_matches_type(SyncCursor[VectorStore], vector_store, path=["response"]) assert cast(Any, response.is_closed) is True @@ -548,7 +548,7 @@ async def test_path_params_update(self, async_client: AsyncMixedbread) -> None: @parametrize async def test_method_list(self, async_client: AsyncMixedbread) -> None: vector_store = await async_client.vector_stores.list() - assert_matches_type(VectorStoreListResponse, vector_store, path=["response"]) + assert_matches_type(AsyncCursor[VectorStore], vector_store, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncMixedbread) -> None: @@ -558,7 +558,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncMixedbread) include_total=True, q="x", ) - assert_matches_type(VectorStoreListResponse, vector_store, path=["response"]) + assert_matches_type(AsyncCursor[VectorStore], vector_store, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncMixedbread) -> None: @@ -567,7 +567,7 @@ async def test_raw_response_list(self, async_client: AsyncMixedbread) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" vector_store = await response.parse() - assert_matches_type(VectorStoreListResponse, vector_store, path=["response"]) + assert_matches_type(AsyncCursor[VectorStore], vector_store, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncMixedbread) -> None: @@ -576,7 +576,7 @@ async def test_streaming_response_list(self, async_client: AsyncMixedbread) -> N assert response.http_request.headers.get("X-Stainless-Lang") == "python" vector_store = await response.parse() - assert_matches_type(VectorStoreListResponse, vector_store, path=["response"]) + assert_matches_type(AsyncCursor[VectorStore], vector_store, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/vector_stores/test_files.py b/tests/api_resources/vector_stores/test_files.py index 3d125ccd..350624fe 100644 --- a/tests/api_resources/vector_stores/test_files.py +++ b/tests/api_resources/vector_stores/test_files.py @@ -9,9 +9,9 @@ from mixedbread import Mixedbread, AsyncMixedbread from tests.utils import assert_matches_type +from mixedbread.pagination import SyncCursor, AsyncCursor from mixedbread.types.vector_stores import ( VectorStoreFile, - FileListResponse, FileDeleteResponse, FileSearchResponse, ) @@ -134,7 +134,7 @@ def test_method_list(self, client: Mixedbread) -> None: file = client.vector_stores.files.list( vector_store_identifier="vector_store_identifier", ) - assert_matches_type(FileListResponse, file, path=["response"]) + assert_matches_type(SyncCursor[VectorStoreFile], file, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Mixedbread) -> None: @@ -145,7 +145,7 @@ def test_method_list_with_all_params(self, client: Mixedbread) -> None: include_total=True, statuses=["pending"], ) - assert_matches_type(FileListResponse, file, path=["response"]) + assert_matches_type(SyncCursor[VectorStoreFile], file, path=["response"]) @parametrize def test_raw_response_list(self, client: Mixedbread) -> None: @@ -156,7 +156,7 @@ def test_raw_response_list(self, client: Mixedbread) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = response.parse() - assert_matches_type(FileListResponse, file, path=["response"]) + assert_matches_type(SyncCursor[VectorStoreFile], file, path=["response"]) @parametrize def test_streaming_response_list(self, client: Mixedbread) -> None: @@ -167,7 +167,7 @@ def test_streaming_response_list(self, client: Mixedbread) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = response.parse() - assert_matches_type(FileListResponse, file, path=["response"]) + assert_matches_type(SyncCursor[VectorStoreFile], file, path=["response"]) assert cast(Any, response.is_closed) is True @@ -436,7 +436,7 @@ async def test_method_list(self, async_client: AsyncMixedbread) -> None: file = await async_client.vector_stores.files.list( vector_store_identifier="vector_store_identifier", ) - assert_matches_type(FileListResponse, file, path=["response"]) + assert_matches_type(AsyncCursor[VectorStoreFile], file, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncMixedbread) -> None: @@ -447,7 +447,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncMixedbread) include_total=True, statuses=["pending"], ) - assert_matches_type(FileListResponse, file, path=["response"]) + assert_matches_type(AsyncCursor[VectorStoreFile], file, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncMixedbread) -> None: @@ -458,7 +458,7 @@ async def test_raw_response_list(self, async_client: AsyncMixedbread) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = await response.parse() - assert_matches_type(FileListResponse, file, path=["response"]) + assert_matches_type(AsyncCursor[VectorStoreFile], file, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncMixedbread) -> None: @@ -469,7 +469,7 @@ async def test_streaming_response_list(self, async_client: AsyncMixedbread) -> N assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = await response.parse() - assert_matches_type(FileListResponse, file, path=["response"]) + assert_matches_type(AsyncCursor[VectorStoreFile], file, path=["response"]) assert cast(Any, response.is_closed) is True From fd31f318ed999cb6bc92a3d3cad0d2fb4f3eb24f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 25 Jun 2025 13:32:23 +0000 Subject: [PATCH 2/3] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 8c28e2d6..70831519 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 49 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/mixedbread%2Fmixedbread-fd1562786a889e981d7d9b30d7f4b29d3d2ea11a8c30e19b919fae07ea355ccd.yml openapi_spec_hash: 1d83645e7d7bc1b6ccfc1ecc7cca656a -config_hash: a36f4234467ae4cd0bea12552fcaaa4e +config_hash: cc68e7e1e58a14763975c9396c8600ae From b238f7c406bdaddee4d5f861654173cd034726a2 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 25 Jun 2025 13:32:41 +0000 Subject: [PATCH 3/3] release: 0.11.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 ++++++++ pyproject.toml | 2 +- src/mixedbread/_version.py | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 091cfb12..f7014c35 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.10.0" + ".": "0.11.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index ac2c9fb9..19a94e04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.11.0 (2025-06-25) + +Full Changelog: [v0.10.0...v0.11.0](https://github.com/mixedbread-ai/mixedbread-python/compare/v0.10.0...v0.11.0) + +### Features + +* **api:** update via SDK Studio ([40597d6](https://github.com/mixedbread-ai/mixedbread-python/commit/40597d61653f176b02ba776cb15229a369891cf9)) + ## 0.10.0 (2025-06-25) Full Changelog: [v0.9.0...v0.10.0](https://github.com/mixedbread-ai/mixedbread-python/compare/v0.9.0...v0.10.0) diff --git a/pyproject.toml b/pyproject.toml index d4a54e06..59f0d0fe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "mixedbread" -version = "0.10.0" +version = "0.11.0" description = "The official Python library for the Mixedbread API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/mixedbread/_version.py b/src/mixedbread/_version.py index 10f2a576..0341bb70 100644 --- a/src/mixedbread/_version.py +++ b/src/mixedbread/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "mixedbread" -__version__ = "0.10.0" # x-release-please-version +__version__ = "0.11.0" # x-release-please-version