From a3e3b23a5e9c95daaf19d1beb84a07a9a61bf2f3 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 11 Aug 2025 07:35:05 +0000
Subject: [PATCH 1/2] feat(api): update via SDK Studio
---
.stats.yml | 2 +-
api.md | 3 +-
.../resources/vector_stores/files.py | 90 +++++++++----------
.../types/vector_stores/__init__.py | 1 +
.../types/vector_stores/file_list_params.py | 17 +++-
.../types/vector_stores/file_list_response.py | 69 ++++++++++++++
.../api_resources/vector_stores/test_files.py | 32 ++++---
7 files changed, 153 insertions(+), 61 deletions(-)
create mode 100644 src/mixedbread/types/vector_stores/file_list_response.py
diff --git a/.stats.yml b/.stats.yml
index c7586392..33d7691d 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-4983c57f5143aaeadfbb4af35595570e613035ae500ff1597fdf600cc2a48959.yml
openapi_spec_hash: ecc0a6cfe61c3c959d034d094f36befe
-config_hash: 810d9712d3d0d6a1f50d71a25511d8a7
+config_hash: ac27678c24558b71ee39b3db54fa12da
diff --git a/api.md b/api.md
index 257f5d28..f251791d 100644
--- a/api.md
+++ b/api.md
@@ -63,6 +63,7 @@ from mixedbread.types.vector_stores import (
ScoredVectorStoreFile,
VectorStoreFileStatus,
VectorStoreFile,
+ FileListResponse,
FileDeleteResponse,
FileSearchResponse,
)
@@ -72,7 +73,7 @@ Methods:
- client.vector_stores.files.create(vector_store_identifier, \*\*params) -> VectorStoreFile
- client.vector_stores.files.retrieve(file_id, \*, vector_store_identifier, \*\*params) -> VectorStoreFile
-- client.vector_stores.files.list(vector_store_identifier, \*\*params) -> SyncCursor[VectorStoreFile]
+- client.vector_stores.files.list(vector_store_identifier, \*\*params) -> FileListResponse
- client.vector_stores.files.delete(file_id, \*, vector_store_identifier) -> FileDeleteResponse
- client.vector_stores.files.search(\*\*params) -> FileSearchResponse
diff --git a/src/mixedbread/resources/vector_stores/files.py b/src/mixedbread/resources/vector_stores/files.py
index 44d28868..7f1ef7c7 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 ...pagination import SyncCursor, AsyncCursor
-from ..._base_client import AsyncPaginator, make_request_options
+from ..._base_client import make_request_options
from ...types.vector_stores import file_list_params, file_create_params, file_search_params, file_retrieve_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
@@ -171,18 +171,19 @@ def list(
before: Optional[str] | NotGiven = NOT_GIVEN,
include_total: bool | NotGiven = NOT_GIVEN,
statuses: Optional[List[VectorStoreFileStatus]] | NotGiven = NOT_GIVEN,
+ metadata_filter: Optional[file_list_params.MetadataFilter] | 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,
- ) -> SyncCursor[VectorStoreFile]:
+ ) -> FileListResponse:
"""
- List files indexed in a vector store with pagination.
+ List files indexed in a vector store with pagination and metadata filter.
Args: vector_store_identifier: The ID or name of the vector store pagination:
- Pagination parameters
+ Pagination parameters and metadata filter
Returns: VectorStoreFileListResponse: Paginated list of vector store files
@@ -201,6 +202,8 @@ def list(
statuses: Status to filter by
+ metadata_filter: Metadata filter to apply to the query
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -213,26 +216,23 @@ def list(
raise ValueError(
f"Expected a non-empty value for `vector_store_identifier` but received {vector_store_identifier!r}"
)
- return self._get_api_list(
- f"/v1/vector_stores/{vector_store_identifier}/files",
- page=SyncCursor[VectorStoreFile],
+ return self._post(
+ f"/v1/vector_stores/{vector_store_identifier}/files/list",
+ body=maybe_transform(
+ {
+ "limit": limit,
+ "after": after,
+ "before": before,
+ "include_total": include_total,
+ "statuses": statuses,
+ "metadata_filter": metadata_filter,
+ },
+ file_list_params.FileListParams,
+ ),
options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "limit": limit,
- "after": after,
- "before": before,
- "include_total": include_total,
- "statuses": statuses,
- },
- file_list_params.FileListParams,
- ),
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- model=VectorStoreFile,
+ cast_to=FileListResponse,
)
def delete(
@@ -600,7 +600,7 @@ async def retrieve(
cast_to=VectorStoreFile,
)
- def list(
+ async def list(
self,
vector_store_identifier: str,
*,
@@ -609,18 +609,19 @@ def list(
before: Optional[str] | NotGiven = NOT_GIVEN,
include_total: bool | NotGiven = NOT_GIVEN,
statuses: Optional[List[VectorStoreFileStatus]] | NotGiven = NOT_GIVEN,
+ metadata_filter: Optional[file_list_params.MetadataFilter] | 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,
- ) -> AsyncPaginator[VectorStoreFile, AsyncCursor[VectorStoreFile]]:
+ ) -> FileListResponse:
"""
- List files indexed in a vector store with pagination.
+ List files indexed in a vector store with pagination and metadata filter.
Args: vector_store_identifier: The ID or name of the vector store pagination:
- Pagination parameters
+ Pagination parameters and metadata filter
Returns: VectorStoreFileListResponse: Paginated list of vector store files
@@ -639,6 +640,8 @@ def list(
statuses: Status to filter by
+ metadata_filter: Metadata filter to apply to the query
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -651,26 +654,23 @@ def list(
raise ValueError(
f"Expected a non-empty value for `vector_store_identifier` but received {vector_store_identifier!r}"
)
- return self._get_api_list(
- f"/v1/vector_stores/{vector_store_identifier}/files",
- page=AsyncCursor[VectorStoreFile],
+ return await self._post(
+ f"/v1/vector_stores/{vector_store_identifier}/files/list",
+ body=await async_maybe_transform(
+ {
+ "limit": limit,
+ "after": after,
+ "before": before,
+ "include_total": include_total,
+ "statuses": statuses,
+ "metadata_filter": metadata_filter,
+ },
+ file_list_params.FileListParams,
+ ),
options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "limit": limit,
- "after": after,
- "before": before,
- "include_total": include_total,
- "statuses": statuses,
- },
- file_list_params.FileListParams,
- ),
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- model=VectorStoreFile,
+ cast_to=FileListResponse,
)
async def delete(
diff --git a/src/mixedbread/types/vector_stores/__init__.py b/src/mixedbread/types/vector_stores/__init__.py
index 6919f613..dcfaa05b 100644
--- a/src/mixedbread/types/vector_stores/__init__.py
+++ b/src/mixedbread/types/vector_stores/__init__.py
@@ -5,6 +5,7 @@
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_params.py b/src/mixedbread/types/vector_stores/file_list_params.py
index 49fe0c08..a4ac03c8 100644
--- a/src/mixedbread/types/vector_stores/file_list_params.py
+++ b/src/mixedbread/types/vector_stores/file_list_params.py
@@ -2,12 +2,13 @@
from __future__ import annotations
-from typing import List, Optional
-from typing_extensions import TypedDict
+from typing import List, Union, Iterable, Optional
+from typing_extensions import TypeAlias, TypedDict
from .vector_store_file_status import VectorStoreFileStatus
+from ..shared_params.search_filter_condition import SearchFilterCondition
-__all__ = ["FileListParams"]
+__all__ = ["FileListParams", "MetadataFilter", "MetadataFilterUnionMember2"]
class FileListParams(TypedDict, total=False):
@@ -31,3 +32,13 @@ class FileListParams(TypedDict, total=False):
statuses: Optional[List[VectorStoreFileStatus]]
"""Status to filter by"""
+
+ metadata_filter: Optional[MetadataFilter]
+ """Metadata filter to apply to the query"""
+
+
+MetadataFilterUnionMember2: TypeAlias = Union["SearchFilter", SearchFilterCondition]
+
+MetadataFilter: TypeAlias = Union["SearchFilter", SearchFilterCondition, Iterable[MetadataFilterUnionMember2]]
+
+from ..shared_params.search_filter import SearchFilter
diff --git a/src/mixedbread/types/vector_stores/file_list_response.py b/src/mixedbread/types/vector_stores/file_list_response.py
new file mode 100644
index 00000000..252d1c93
--- /dev/null
+++ b/src/mixedbread/types/vector_stores/file_list_response.py
@@ -0,0 +1,69 @@
+# 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):
+ has_more: bool
+ """
+ Contextual direction-aware flag: True if more items exist in the requested
+ pagination direction. For 'after': more items after this page. For 'before':
+ more items before this page.
+ """
+
+ first_cursor: Optional[str] = None
+ """Cursor of the first item in this page.
+
+ Use for backward pagination. None if page is empty.
+ """
+
+ last_cursor: Optional[str] = None
+ """Cursor of the last item in this page.
+
+ Use for forward pagination. None if page is empty.
+ """
+
+ total: Optional[int] = None
+ """Total number of items available across all pages.
+
+ Only included when include_total=true was requested. Expensive operation - use
+ sparingly.
+ """
+
+
+class FileListResponse(BaseModel):
+ pagination: Pagination
+ """Response model for cursor-based pagination.
+
+ Examples: Forward pagination response: { "has_more": true, "first_cursor":
+ "eyJjcmVhdGVkX2F0IjoiMjAyNC0xMi0zMSIsImlkIjoiYWJjMTIzIn0=", "last_cursor":
+ "eyJjcmVhdGVkX2F0IjoiMjAyNC0xMi0zMCIsImlkIjoieHl6Nzg5In0=", "total": null }
+
+ Final page response:
+ {
+ "has_more": false,
+ "first_cursor": "eyJjcmVhdGVkX2F0IjoiMjAyNC0xMi0yOSIsImlkIjoibGFzdDEyMyJ9",
+ "last_cursor": "eyJjcmVhdGVkX2F0IjoiMjAyNC0xMi0yOCIsImlkIjoiZmluYWw0NTYifQ==",
+ "total": 42
+ }
+
+ Empty results:
+ {
+ "has_more": false,
+ "first_cursor": null,
+ "last_cursor": null,
+ "total": 0
+ }
+ """
+
+ 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/vector_stores/test_files.py b/tests/api_resources/vector_stores/test_files.py
index 13922a78..15a1c34b 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,
)
@@ -143,7 +143,7 @@ def test_method_list(self, client: Mixedbread) -> None:
file = client.vector_stores.files.list(
vector_store_identifier="vector_store_identifier",
)
- assert_matches_type(SyncCursor[VectorStoreFile], file, path=["response"])
+ assert_matches_type(FileListResponse, file, path=["response"])
@parametrize
def test_method_list_with_all_params(self, client: Mixedbread) -> None:
@@ -153,9 +153,14 @@ def test_method_list_with_all_params(self, client: Mixedbread) -> None:
after="eyJjcmVhdGVkX2F0IjoiMjAyNC0xMi0zMVQyMzo1OTo1OS4wMDBaIiwiaWQiOiJhYmMxMjMifQ==",
before="eyJjcmVhdGVkX2F0IjoiMjAyNC0xMi0zMVQyMzo1OTo1OS4wMDBaIiwiaWQiOiJhYmMxMjMifQ==",
include_total=False,
- statuses=["pending", "in_progress"],
+ statuses=["pending"],
+ metadata_filter={
+ "all": [],
+ "any": [],
+ "none": [],
+ },
)
- assert_matches_type(SyncCursor[VectorStoreFile], file, path=["response"])
+ assert_matches_type(FileListResponse, file, path=["response"])
@parametrize
def test_raw_response_list(self, client: Mixedbread) -> None:
@@ -166,7 +171,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(SyncCursor[VectorStoreFile], file, path=["response"])
+ assert_matches_type(FileListResponse, file, path=["response"])
@parametrize
def test_streaming_response_list(self, client: Mixedbread) -> None:
@@ -177,7 +182,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(SyncCursor[VectorStoreFile], file, path=["response"])
+ assert_matches_type(FileListResponse, file, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -423,7 +428,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(AsyncCursor[VectorStoreFile], file, path=["response"])
+ assert_matches_type(FileListResponse, file, path=["response"])
@parametrize
async def test_method_list_with_all_params(self, async_client: AsyncMixedbread) -> None:
@@ -433,9 +438,14 @@ async def test_method_list_with_all_params(self, async_client: AsyncMixedbread)
after="eyJjcmVhdGVkX2F0IjoiMjAyNC0xMi0zMVQyMzo1OTo1OS4wMDBaIiwiaWQiOiJhYmMxMjMifQ==",
before="eyJjcmVhdGVkX2F0IjoiMjAyNC0xMi0zMVQyMzo1OTo1OS4wMDBaIiwiaWQiOiJhYmMxMjMifQ==",
include_total=False,
- statuses=["pending", "in_progress"],
+ statuses=["pending"],
+ metadata_filter={
+ "all": [],
+ "any": [],
+ "none": [],
+ },
)
- assert_matches_type(AsyncCursor[VectorStoreFile], file, path=["response"])
+ assert_matches_type(FileListResponse, file, path=["response"])
@parametrize
async def test_raw_response_list(self, async_client: AsyncMixedbread) -> None:
@@ -446,7 +456,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(AsyncCursor[VectorStoreFile], file, path=["response"])
+ assert_matches_type(FileListResponse, file, path=["response"])
@parametrize
async def test_streaming_response_list(self, async_client: AsyncMixedbread) -> None:
@@ -457,7 +467,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(AsyncCursor[VectorStoreFile], file, path=["response"])
+ assert_matches_type(FileListResponse, file, path=["response"])
assert cast(Any, response.is_closed) is True
From e7a9076d884c88bc18d0325566f5f4fa008827c7 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 11 Aug 2025 07:35:24 +0000
Subject: [PATCH 2/2] release: 0.23.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 3f63a672..7f3f5c84 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.22.1"
+ ".": "0.23.0"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8314ff8b..186715c1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog
+## 0.23.0 (2025-08-11)
+
+Full Changelog: [v0.22.1...v0.23.0](https://github.com/mixedbread-ai/mixedbread-python/compare/v0.22.1...v0.23.0)
+
+### Features
+
+* **api:** update via SDK Studio ([a3e3b23](https://github.com/mixedbread-ai/mixedbread-python/commit/a3e3b23a5e9c95daaf19d1beb84a07a9a61bf2f3))
+
## 0.22.1 (2025-08-09)
Full Changelog: [v0.22.0...v0.22.1](https://github.com/mixedbread-ai/mixedbread-python/compare/v0.22.0...v0.22.1)
diff --git a/pyproject.toml b/pyproject.toml
index 14fac4d6..a3533921 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "mixedbread"
-version = "0.22.1"
+version = "0.23.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 fc0f2056..4927e510 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.22.1" # x-release-please-version
+__version__ = "0.23.0" # x-release-please-version