diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 2aca35ae..4208b5cb 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.5.0"
+ ".": "0.6.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index 71c5ffa2..c6e434cd 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-82c2c1c322149cd73b2e8e45f475919b941752a89e74464ccecd1aee9352e9be.yml
-openapi_spec_hash: 07482ed86f5ccf7b480c514d6d5ebb15
-config_hash: 167171738605c297aa5e8bc73abc66e3
+configured_endpoints: 48
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/mixedbread%2Fmixedbread-a331b701867ba3d3dd907c8389fde663be4fda24c91e23f54f4dde8a6ade683f.yml
+openapi_spec_hash: 95587d9746abb97d5b294bfedf86b782
+config_hash: 8545159b6ba2d638b8a2e7bbed6f04e7
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f4dee4fb..8a341037 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,32 @@
# Changelog
+## 0.6.0 (2025-06-13)
+
+Full Changelog: [v0.5.0...v0.6.0](https://github.com/mixedbread-ai/mixedbread-python/compare/v0.5.0...v0.6.0)
+
+### Features
+
+* **api:** api update ([8ada0ea](https://github.com/mixedbread-ai/mixedbread-python/commit/8ada0eaeeed29b8ee2a08cf436077ee2f729794a))
+* **api:** api update ([22e5269](https://github.com/mixedbread-ai/mixedbread-python/commit/22e52693cb2f02fb20c0f7ca8f97d572a1091f6f))
+* **api:** api update ([eec921b](https://github.com/mixedbread-ai/mixedbread-python/commit/eec921b939205565f11790b08458f3e74df6e8a3))
+* **api:** api update ([0296d95](https://github.com/mixedbread-ai/mixedbread-python/commit/0296d958b5d8e82e2626fc04f9618a6423803515))
+* **api:** update via SDK Studio ([56f4e89](https://github.com/mixedbread-ai/mixedbread-python/commit/56f4e890d75c0cc54898f65f4087a828fe4bcc4e))
+* **api:** update via SDK Studio ([ed99b06](https://github.com/mixedbread-ai/mixedbread-python/commit/ed99b067eba308da0bb4ff24623d32b3339563a1))
+* **client:** add follow_redirects request option ([5f0a4ab](https://github.com/mixedbread-ai/mixedbread-python/commit/5f0a4abbecd635ad655480514685281891fd8699))
+
+
+### Bug Fixes
+
+* **client:** correctly parse binary response | stream ([786bd6a](https://github.com/mixedbread-ai/mixedbread-python/commit/786bd6aeeac6fb7af0ffb1f00b6485dd253bd8fa))
+* **docs/api:** remove references to nonexistent types ([43c342b](https://github.com/mixedbread-ai/mixedbread-python/commit/43c342bb106371ea6057969578dc55af713f225e))
+
+
+### Chores
+
+* **docs:** remove reference to rye shell ([c0c8bfd](https://github.com/mixedbread-ai/mixedbread-python/commit/c0c8bfdeac4c2ed4b7d381a9faef43485e5904de))
+* **docs:** remove unnecessary param examples ([54ef7c7](https://github.com/mixedbread-ai/mixedbread-python/commit/54ef7c77e392577a3038552a4a859b6351c6ddf4))
+* **tests:** run tests in parallel ([064a793](https://github.com/mixedbread-ai/mixedbread-python/commit/064a793c8269a6e3a30a1c84e6d7a3a783ffa31f))
+
## 0.5.0 (2025-05-26)
Full Changelog: [v0.4.0...v0.5.0](https://github.com/mixedbread-ai/mixedbread-python/compare/v0.4.0...v0.5.0)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e9ccd896..0b147f05 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -17,8 +17,7 @@ $ rye sync --all-features
You can then run scripts using `rye run python script.py` or by activating the virtual environment:
```sh
-$ rye shell
-# or manually activate - https://docs.python.org/3/library/venv.html#how-venvs-work
+# Activate the virtual environment - https://docs.python.org/3/library/venv.html#how-venvs-work
$ source .venv/bin/activate
# now you can omit the `rye run` prefix
diff --git a/README.md b/README.md
index 831cfdec..24d13985 100644
--- a/README.md
+++ b/README.md
@@ -152,10 +152,7 @@ from mixedbread import Mixedbread
client = Mixedbread()
vector_store = client.vector_stores.create(
- expires_after={
- "anchor": "last_active_at",
- "days": 0,
- },
+ expires_after={},
)
print(vector_store.expires_after)
```
diff --git a/api.md b/api.md
index ff98c770..0008e67f 100644
--- a/api.md
+++ b/api.md
@@ -46,10 +46,10 @@ from mixedbread.types import (
Methods:
- client.vector_stores.create(\*\*params) -> VectorStore
-- client.vector_stores.retrieve(vector_store_id) -> VectorStore
-- client.vector_stores.update(vector_store_id, \*\*params) -> VectorStore
+- client.vector_stores.retrieve(vector_store_identifier) -> VectorStore
+- client.vector_stores.update(vector_store_identifier, \*\*params) -> VectorStore
- client.vector_stores.list(\*\*params) -> SyncLimitOffset[VectorStore]
-- client.vector_stores.delete(vector_store_id) -> VectorStoreDeleteResponse
+- client.vector_stores.delete(vector_store_identifier) -> VectorStoreDeleteResponse
- client.vector_stores.question_answering(\*\*params) -> VectorStoreQuestionAnsweringResponse
- client.vector_stores.search(\*\*params) -> VectorStoreSearchResponse
@@ -68,10 +68,10 @@ from mixedbread.types.vector_stores import (
Methods:
-- client.vector_stores.files.create(vector_store_id, \*\*params) -> VectorStoreFile
-- client.vector_stores.files.retrieve(file_id, \*, vector_store_id) -> VectorStoreFile
-- client.vector_stores.files.list(vector_store_id, \*\*params) -> SyncLimitOffset[VectorStoreFile]
-- client.vector_stores.files.delete(file_id, \*, vector_store_id) -> FileDeleteResponse
+- 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) -> SyncLimitOffset[VectorStoreFile]
+- client.vector_stores.files.delete(file_id, \*, vector_store_identifier) -> FileDeleteResponse
- client.vector_stores.files.search(\*\*params) -> FileSearchResponse
# Parsing
@@ -170,18 +170,6 @@ Methods:
- client.embeddings.create(\*\*params) -> EmbeddingCreateResponse
-# Chat
-
-Types:
-
-```python
-from mixedbread.types import ChatCreateCompletionResponse
-```
-
-Methods:
-
-- client.chat.create_completion() -> object
-
# DataSources
Types:
diff --git a/pyproject.toml b/pyproject.toml
index b6e83d86..6de28979 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "mixedbread"
-version = "0.5.0"
+version = "0.6.0"
description = "The official Python library for the Mixedbread API"
dynamic = ["readme"]
license = "Apache-2.0"
@@ -54,6 +54,7 @@ dev-dependencies = [
"importlib-metadata>=6.7.0",
"rich>=13.7.1",
"nest_asyncio==1.6.0",
+ "pytest-xdist>=3.6.1",
]
[tool.rye.scripts]
@@ -125,7 +126,7 @@ replacement = '[\1](https://github.com/mixedbread-ai/mixedbread-python/tree/main
[tool.pytest.ini_options]
testpaths = ["tests"]
-addopts = "--tb=short"
+addopts = "--tb=short -n auto"
xfail_strict = true
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "session"
diff --git a/requirements-dev.lock b/requirements-dev.lock
index 4d2d4266..e4090452 100644
--- a/requirements-dev.lock
+++ b/requirements-dev.lock
@@ -30,6 +30,8 @@ distro==1.8.0
exceptiongroup==1.2.2
# via anyio
# via pytest
+execnet==2.1.1
+ # via pytest-xdist
filelock==3.12.4
# via virtualenv
h11==0.14.0
@@ -72,7 +74,9 @@ pygments==2.18.0
pyright==1.1.399
pytest==8.3.3
# via pytest-asyncio
+ # via pytest-xdist
pytest-asyncio==0.24.0
+pytest-xdist==3.7.0
python-dateutil==2.8.2
# via time-machine
pytz==2023.3.post1
diff --git a/src/mixedbread/_base_client.py b/src/mixedbread/_base_client.py
index 72f949dc..44036510 100644
--- a/src/mixedbread/_base_client.py
+++ b/src/mixedbread/_base_client.py
@@ -960,6 +960,9 @@ def request(
if self.custom_auth is not None:
kwargs["auth"] = self.custom_auth
+ if options.follow_redirects is not None:
+ kwargs["follow_redirects"] = options.follow_redirects
+
log.debug("Sending HTTP Request: %s %s", request.method, request.url)
response = None
@@ -1068,7 +1071,14 @@ def _process_response(
) -> ResponseT:
origin = get_origin(cast_to) or cast_to
- if inspect.isclass(origin) and issubclass(origin, BaseAPIResponse):
+ if (
+ inspect.isclass(origin)
+ and issubclass(origin, BaseAPIResponse)
+ # we only want to actually return the custom BaseAPIResponse class if we're
+ # returning the raw response, or if we're not streaming SSE, as if we're streaming
+ # SSE then `cast_to` doesn't actively reflect the type we need to parse into
+ and (not stream or bool(response.request.headers.get(RAW_RESPONSE_HEADER)))
+ ):
if not issubclass(origin, APIResponse):
raise TypeError(f"API Response types must subclass {APIResponse}; Received {origin}")
@@ -1460,6 +1470,9 @@ async def request(
if self.custom_auth is not None:
kwargs["auth"] = self.custom_auth
+ if options.follow_redirects is not None:
+ kwargs["follow_redirects"] = options.follow_redirects
+
log.debug("Sending HTTP Request: %s %s", request.method, request.url)
response = None
@@ -1568,7 +1581,14 @@ async def _process_response(
) -> ResponseT:
origin = get_origin(cast_to) or cast_to
- if inspect.isclass(origin) and issubclass(origin, BaseAPIResponse):
+ if (
+ inspect.isclass(origin)
+ and issubclass(origin, BaseAPIResponse)
+ # we only want to actually return the custom BaseAPIResponse class if we're
+ # returning the raw response, or if we're not streaming SSE, as if we're streaming
+ # SSE then `cast_to` doesn't actively reflect the type we need to parse into
+ and (not stream or bool(response.request.headers.get(RAW_RESPONSE_HEADER)))
+ ):
if not issubclass(origin, AsyncAPIResponse):
raise TypeError(f"API Response types must subclass {AsyncAPIResponse}; Received {origin}")
diff --git a/src/mixedbread/_client.py b/src/mixedbread/_client.py
index 87e724e0..f75adc2f 100644
--- a/src/mixedbread/_client.py
+++ b/src/mixedbread/_client.py
@@ -36,7 +36,7 @@
async_to_raw_response_wrapper,
async_to_streamed_response_wrapper,
)
-from .resources import chat, files, api_keys, embeddings
+from .resources import files, api_keys, embeddings
from ._streaming import Stream as Stream, AsyncStream as AsyncStream
from ._exceptions import APIStatusError, MixedbreadError
from ._base_client import (
@@ -78,7 +78,6 @@ class Mixedbread(SyncAPIClient):
files: files.FilesResource
extractions: extractions.ExtractionsResource
embeddings: embeddings.EmbeddingsResource
- chat: chat.ChatResource
data_sources: data_sources.DataSourcesResource
api_keys: api_keys.APIKeysResource
with_raw_response: MixedbreadWithRawResponse
@@ -167,7 +166,6 @@ def __init__(
self.files = files.FilesResource(self)
self.extractions = extractions.ExtractionsResource(self)
self.embeddings = embeddings.EmbeddingsResource(self)
- self.chat = chat.ChatResource(self)
self.data_sources = data_sources.DataSourcesResource(self)
self.api_keys = api_keys.APIKeysResource(self)
self.with_raw_response = MixedbreadWithRawResponse(self)
@@ -441,7 +439,6 @@ class AsyncMixedbread(AsyncAPIClient):
files: files.AsyncFilesResource
extractions: extractions.AsyncExtractionsResource
embeddings: embeddings.AsyncEmbeddingsResource
- chat: chat.AsyncChatResource
data_sources: data_sources.AsyncDataSourcesResource
api_keys: api_keys.AsyncAPIKeysResource
with_raw_response: AsyncMixedbreadWithRawResponse
@@ -530,7 +527,6 @@ def __init__(
self.files = files.AsyncFilesResource(self)
self.extractions = extractions.AsyncExtractionsResource(self)
self.embeddings = embeddings.AsyncEmbeddingsResource(self)
- self.chat = chat.AsyncChatResource(self)
self.data_sources = data_sources.AsyncDataSourcesResource(self)
self.api_keys = api_keys.AsyncAPIKeysResource(self)
self.with_raw_response = AsyncMixedbreadWithRawResponse(self)
@@ -805,7 +801,6 @@ def __init__(self, client: Mixedbread) -> None:
self.files = files.FilesResourceWithRawResponse(client.files)
self.extractions = extractions.ExtractionsResourceWithRawResponse(client.extractions)
self.embeddings = embeddings.EmbeddingsResourceWithRawResponse(client.embeddings)
- self.chat = chat.ChatResourceWithRawResponse(client.chat)
self.data_sources = data_sources.DataSourcesResourceWithRawResponse(client.data_sources)
self.api_keys = api_keys.APIKeysResourceWithRawResponse(client.api_keys)
@@ -827,7 +822,6 @@ def __init__(self, client: AsyncMixedbread) -> None:
self.files = files.AsyncFilesResourceWithRawResponse(client.files)
self.extractions = extractions.AsyncExtractionsResourceWithRawResponse(client.extractions)
self.embeddings = embeddings.AsyncEmbeddingsResourceWithRawResponse(client.embeddings)
- self.chat = chat.AsyncChatResourceWithRawResponse(client.chat)
self.data_sources = data_sources.AsyncDataSourcesResourceWithRawResponse(client.data_sources)
self.api_keys = api_keys.AsyncAPIKeysResourceWithRawResponse(client.api_keys)
@@ -849,7 +843,6 @@ def __init__(self, client: Mixedbread) -> None:
self.files = files.FilesResourceWithStreamingResponse(client.files)
self.extractions = extractions.ExtractionsResourceWithStreamingResponse(client.extractions)
self.embeddings = embeddings.EmbeddingsResourceWithStreamingResponse(client.embeddings)
- self.chat = chat.ChatResourceWithStreamingResponse(client.chat)
self.data_sources = data_sources.DataSourcesResourceWithStreamingResponse(client.data_sources)
self.api_keys = api_keys.APIKeysResourceWithStreamingResponse(client.api_keys)
@@ -871,7 +864,6 @@ def __init__(self, client: AsyncMixedbread) -> None:
self.files = files.AsyncFilesResourceWithStreamingResponse(client.files)
self.extractions = extractions.AsyncExtractionsResourceWithStreamingResponse(client.extractions)
self.embeddings = embeddings.AsyncEmbeddingsResourceWithStreamingResponse(client.embeddings)
- self.chat = chat.AsyncChatResourceWithStreamingResponse(client.chat)
self.data_sources = data_sources.AsyncDataSourcesResourceWithStreamingResponse(client.data_sources)
self.api_keys = api_keys.AsyncAPIKeysResourceWithStreamingResponse(client.api_keys)
diff --git a/src/mixedbread/_models.py b/src/mixedbread/_models.py
index 798956f1..4f214980 100644
--- a/src/mixedbread/_models.py
+++ b/src/mixedbread/_models.py
@@ -737,6 +737,7 @@ class FinalRequestOptionsInput(TypedDict, total=False):
idempotency_key: str
json_data: Body
extra_json: AnyMapping
+ follow_redirects: bool
@final
@@ -750,6 +751,7 @@ class FinalRequestOptions(pydantic.BaseModel):
files: Union[HttpxRequestFiles, None] = None
idempotency_key: Union[str, None] = None
post_parser: Union[Callable[[Any], Any], NotGiven] = NotGiven()
+ follow_redirects: Union[bool, None] = None
# It should be noted that we cannot use `json` here as that would override
# a BaseModel method in an incompatible fashion.
diff --git a/src/mixedbread/_types.py b/src/mixedbread/_types.py
index b1e781f8..6fdd2f2b 100644
--- a/src/mixedbread/_types.py
+++ b/src/mixedbread/_types.py
@@ -100,6 +100,7 @@ class RequestOptions(TypedDict, total=False):
params: Query
extra_json: AnyMapping
idempotency_key: str
+ follow_redirects: bool
# Sentinel class used until PEP 0661 is accepted
@@ -215,3 +216,4 @@ class _GenericAlias(Protocol):
class HttpxSendArgs(TypedDict, total=False):
auth: httpx.Auth
+ follow_redirects: bool
diff --git a/src/mixedbread/_version.py b/src/mixedbread/_version.py
index 7a42cf4e..6060c6be 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.5.0" # x-release-please-version
+__version__ = "0.6.0" # x-release-please-version
diff --git a/src/mixedbread/resources/__init__.py b/src/mixedbread/resources/__init__.py
index 241510a2..284cc1cb 100644
--- a/src/mixedbread/resources/__init__.py
+++ b/src/mixedbread/resources/__init__.py
@@ -1,13 +1,5 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from .chat import (
- ChatResource,
- AsyncChatResource,
- ChatResourceWithRawResponse,
- AsyncChatResourceWithRawResponse,
- ChatResourceWithStreamingResponse,
- AsyncChatResourceWithStreamingResponse,
-)
from .files import (
FilesResource,
AsyncFilesResource,
@@ -96,12 +88,6 @@
"AsyncEmbeddingsResourceWithRawResponse",
"EmbeddingsResourceWithStreamingResponse",
"AsyncEmbeddingsResourceWithStreamingResponse",
- "ChatResource",
- "AsyncChatResource",
- "ChatResourceWithRawResponse",
- "AsyncChatResourceWithRawResponse",
- "ChatResourceWithStreamingResponse",
- "AsyncChatResourceWithStreamingResponse",
"DataSourcesResource",
"AsyncDataSourcesResource",
"DataSourcesResourceWithRawResponse",
diff --git a/src/mixedbread/resources/chat.py b/src/mixedbread/resources/chat.py
deleted file mode 100644
index f9b1b0ce..00000000
--- a/src/mixedbread/resources/chat.py
+++ /dev/null
@@ -1,164 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import httpx
-
-from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven
-from .._compat import cached_property
-from .._resource import SyncAPIResource, AsyncAPIResource
-from .._response import (
- to_raw_response_wrapper,
- to_streamed_response_wrapper,
- async_to_raw_response_wrapper,
- async_to_streamed_response_wrapper,
-)
-from .._base_client import make_request_options
-
-__all__ = ["ChatResource", "AsyncChatResource"]
-
-
-class ChatResource(SyncAPIResource):
- @cached_property
- def with_raw_response(self) -> ChatResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/mixedbread-ai/mixedbread-python#accessing-raw-response-data-eg-headers
- """
- return ChatResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> ChatResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/mixedbread-ai/mixedbread-python#with_streaming_response
- """
- return ChatResourceWithStreamingResponse(self)
-
- def create_completion(
- self,
- *,
- # 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,
- ) -> object:
- """
- Create a chat completion using the provided parameters.
-
- Generates a completion response based on the chat messages and model parameters
- provided. The response can be either a full completion or streamed chunks
- depending on the request parameters.
-
- Args: params: Parameters for creating the chat completion including messages,
- model selection, and generation settings user: The authenticated user making the
- request
-
- Returns: Either a ChatCompletion containing the full response, or
- ChatCompletionChunk for streaming
-
- Raises: HTTPException: If there is an error creating the completion (500)
- """
- return self._post(
- "/v1/chat/completions",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=object,
- )
-
-
-class AsyncChatResource(AsyncAPIResource):
- @cached_property
- def with_raw_response(self) -> AsyncChatResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/mixedbread-ai/mixedbread-python#accessing-raw-response-data-eg-headers
- """
- return AsyncChatResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncChatResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/mixedbread-ai/mixedbread-python#with_streaming_response
- """
- return AsyncChatResourceWithStreamingResponse(self)
-
- async def create_completion(
- self,
- *,
- # 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,
- ) -> object:
- """
- Create a chat completion using the provided parameters.
-
- Generates a completion response based on the chat messages and model parameters
- provided. The response can be either a full completion or streamed chunks
- depending on the request parameters.
-
- Args: params: Parameters for creating the chat completion including messages,
- model selection, and generation settings user: The authenticated user making the
- request
-
- Returns: Either a ChatCompletion containing the full response, or
- ChatCompletionChunk for streaming
-
- Raises: HTTPException: If there is an error creating the completion (500)
- """
- return await self._post(
- "/v1/chat/completions",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=object,
- )
-
-
-class ChatResourceWithRawResponse:
- def __init__(self, chat: ChatResource) -> None:
- self._chat = chat
-
- self.create_completion = to_raw_response_wrapper(
- chat.create_completion,
- )
-
-
-class AsyncChatResourceWithRawResponse:
- def __init__(self, chat: AsyncChatResource) -> None:
- self._chat = chat
-
- self.create_completion = async_to_raw_response_wrapper(
- chat.create_completion,
- )
-
-
-class ChatResourceWithStreamingResponse:
- def __init__(self, chat: ChatResource) -> None:
- self._chat = chat
-
- self.create_completion = to_streamed_response_wrapper(
- chat.create_completion,
- )
-
-
-class AsyncChatResourceWithStreamingResponse:
- def __init__(self, chat: AsyncChatResource) -> None:
- self._chat = chat
-
- self.create_completion = async_to_streamed_response_wrapper(
- chat.create_completion,
- )
diff --git a/src/mixedbread/resources/data_sources/connectors.py b/src/mixedbread/resources/data_sources/connectors.py
index 435ca0e1..c9ab8400 100644
--- a/src/mixedbread/resources/data_sources/connectors.py
+++ b/src/mixedbread/resources/data_sources/connectors.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import Dict, Optional
+from typing import Dict, Union, Optional
import httpx
@@ -53,7 +53,7 @@ def create(
name: str | NotGiven = NOT_GIVEN,
trigger_sync: bool | NotGiven = NOT_GIVEN,
metadata: object | NotGiven = NOT_GIVEN,
- polling_interval: Optional[str] | NotGiven = NOT_GIVEN,
+ polling_interval: Union[int, str, None] | 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,
@@ -80,7 +80,12 @@ def create(
metadata: The metadata of the connector
- polling_interval: The polling interval of the connector
+ polling_interval: Polling interval for the connector. Defaults to 30 minutes if not specified. Can
+ be provided as:
+
+ - int: Number of seconds (e.g., 1800 for 30 minutes)
+ - str: Duration string (e.g., '30m', '1h', '2d') or ISO 8601 format (e.g.,
+ 'PT30M', 'P1D') Valid range: 15 seconds to 30 days
extra_headers: Send extra headers
@@ -163,7 +168,7 @@ def update(
name: Optional[str] | NotGiven = NOT_GIVEN,
metadata: Optional[Dict[str, object]] | NotGiven = NOT_GIVEN,
trigger_sync: Optional[bool] | NotGiven = NOT_GIVEN,
- polling_interval: Optional[str] | NotGiven = NOT_GIVEN,
+ polling_interval: Union[int, str, None] | 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,
@@ -191,7 +196,12 @@ def update(
trigger_sync: Whether the connector should be synced after update
- polling_interval: The polling interval of the connector
+ polling_interval: Polling interval for the connector. Defaults to 30 minutes if not specified. Can
+ be provided as:
+
+ - int: Number of seconds (e.g., 1800 for 30 minutes)
+ - str: Duration string (e.g., '30m', '1h', '2d') or ISO 8601 format (e.g.,
+ 'PT30M', 'P1D') Valid range: 15 seconds to 30 days
extra_headers: Send extra headers
@@ -353,7 +363,7 @@ async def create(
name: str | NotGiven = NOT_GIVEN,
trigger_sync: bool | NotGiven = NOT_GIVEN,
metadata: object | NotGiven = NOT_GIVEN,
- polling_interval: Optional[str] | NotGiven = NOT_GIVEN,
+ polling_interval: Union[int, str, None] | 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,
@@ -380,7 +390,12 @@ async def create(
metadata: The metadata of the connector
- polling_interval: The polling interval of the connector
+ polling_interval: Polling interval for the connector. Defaults to 30 minutes if not specified. Can
+ be provided as:
+
+ - int: Number of seconds (e.g., 1800 for 30 minutes)
+ - str: Duration string (e.g., '30m', '1h', '2d') or ISO 8601 format (e.g.,
+ 'PT30M', 'P1D') Valid range: 15 seconds to 30 days
extra_headers: Send extra headers
@@ -463,7 +478,7 @@ async def update(
name: Optional[str] | NotGiven = NOT_GIVEN,
metadata: Optional[Dict[str, object]] | NotGiven = NOT_GIVEN,
trigger_sync: Optional[bool] | NotGiven = NOT_GIVEN,
- polling_interval: Optional[str] | NotGiven = NOT_GIVEN,
+ polling_interval: Union[int, str, None] | 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,
@@ -491,7 +506,12 @@ async def update(
trigger_sync: Whether the connector should be synced after update
- polling_interval: The polling interval of the connector
+ polling_interval: Polling interval for the connector. Defaults to 30 minutes if not specified. Can
+ be provided as:
+
+ - int: Number of seconds (e.g., 1800 for 30 minutes)
+ - str: Duration string (e.g., '30m', '1h', '2d') or ISO 8601 format (e.g.,
+ 'PT30M', 'P1D') Valid range: 15 seconds to 30 days
extra_headers: Send extra headers
diff --git a/src/mixedbread/resources/data_sources/data_sources.py b/src/mixedbread/resources/data_sources/data_sources.py
index a579c6ac..1f3fc0f9 100644
--- a/src/mixedbread/resources/data_sources/data_sources.py
+++ b/src/mixedbread/resources/data_sources/data_sources.py
@@ -3,17 +3,13 @@
from __future__ import annotations
from typing import Optional
+from typing_extensions import overload
import httpx
-from ...types import (
- DataSourceType,
- data_source_list_params,
- data_source_create_params,
- data_source_update_params,
-)
+from ...types import DataSourceType, data_source_list_params, data_source_create_params, data_source_update_params
from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._utils import required_args, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from .connectors import (
ConnectorsResource,
@@ -35,7 +31,6 @@
from ...types.data_source import DataSource
from ...types.data_source_type import DataSourceType
from ...types.data_source_delete_response import DataSourceDeleteResponse
-from ...types.data_source_oauth2_params_param import DataSourceOauth2ParamsParam
__all__ = ["DataSourcesResource", "AsyncDataSourcesResource"]
@@ -64,13 +59,15 @@ def with_streaming_response(self) -> DataSourcesResourceWithStreamingResponse:
"""
return DataSourcesResourceWithStreamingResponse(self)
+ @overload
def create(
self,
*,
- type: DataSourceType,
+ type: DataSourceType | NotGiven = NOT_GIVEN,
name: str,
metadata: object | NotGiven = NOT_GIVEN,
- auth_params: Optional[DataSourceOauth2ParamsParam] | NotGiven = NOT_GIVEN,
+ auth_params: Optional[data_source_create_params.NotionDataSourceCreateOrUpdateParamsAuthParams]
+ | 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,
@@ -92,7 +89,8 @@ def create(
metadata: The metadata of the data source
- auth_params: Authentication parameters for a OAuth data source.
+ auth_params: The authentication parameters of the data source. Notion supports OAuth2 and API
+ key.
extra_headers: Send extra headers
@@ -102,6 +100,67 @@ def create(
timeout: Override the client-level default timeout for this request, in seconds
"""
+ ...
+
+ @overload
+ def create(
+ self,
+ *,
+ type: DataSourceType | NotGiven = NOT_GIVEN,
+ name: str,
+ metadata: object | NotGiven = NOT_GIVEN,
+ auth_params: Optional[data_source_create_params.LinearDataSourceCreateOrUpdateParamsAuthParams]
+ | 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,
+ ) -> DataSource:
+ """
+ Create a new data source.
+
+ Args: params: The data source to create.
+
+ Returns: The created data source.
+
+ Args:
+ type: The type of data source to create
+
+ name: The name of the data source
+
+ metadata: The metadata of the data source
+
+ auth_params: Base class for OAuth2 create or update parameters.
+
+ 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
+ """
+ ...
+
+ @required_args(["name"])
+ def create(
+ self,
+ *,
+ type: DataSourceType | NotGiven = NOT_GIVEN,
+ name: str,
+ metadata: object | NotGiven = NOT_GIVEN,
+ auth_params: Optional[data_source_create_params.NotionDataSourceCreateOrUpdateParamsAuthParams]
+ | Optional[data_source_create_params.LinearDataSourceCreateOrUpdateParamsAuthParams]
+ | 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,
+ ) -> DataSource:
return self._post(
"/v1/data_sources/",
body=maybe_transform(
@@ -158,13 +217,16 @@ def retrieve(
cast_to=DataSource,
)
+ @overload
def update(
self,
data_source_id: str,
*,
- name: Optional[str] | NotGiven = NOT_GIVEN,
+ type: DataSourceType | NotGiven = NOT_GIVEN,
+ name: str,
metadata: object | NotGiven = NOT_GIVEN,
- auth_params: Optional[DataSourceOauth2ParamsParam] | NotGiven = NOT_GIVEN,
+ auth_params: Optional[data_source_update_params.NotionDataSourceCreateOrUpdateParamsAuthParams]
+ | 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,
@@ -184,11 +246,14 @@ def update(
Args:
data_source_id: The ID of the data source to update
+ type: The type of data source to create
+
name: The name of the data source
metadata: The metadata of the data source
- auth_params: Authentication parameters for a OAuth data source.
+ auth_params: The authentication parameters of the data source. Notion supports OAuth2 and API
+ key.
extra_headers: Send extra headers
@@ -198,12 +263,80 @@ def update(
timeout: Override the client-level default timeout for this request, in seconds
"""
+ ...
+
+ @overload
+ def update(
+ self,
+ data_source_id: str,
+ *,
+ type: DataSourceType | NotGiven = NOT_GIVEN,
+ name: str,
+ metadata: object | NotGiven = NOT_GIVEN,
+ auth_params: Optional[data_source_update_params.LinearDataSourceCreateOrUpdateParamsAuthParams]
+ | 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,
+ ) -> DataSource:
+ """Update a data source.
+
+ Args: data_source_id: The ID of the data source to update.
+
+ params: The data
+ source to update.
+
+ Returns: The updated data source.
+
+ Args:
+ data_source_id: The ID of the data source to update
+
+ type: The type of data source to create
+
+ name: The name of the data source
+
+ metadata: The metadata of the data source
+
+ auth_params: Base class for OAuth2 create or update parameters.
+
+ 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
+ """
+ ...
+
+ @required_args(["name"])
+ def update(
+ self,
+ data_source_id: str,
+ *,
+ type: DataSourceType | NotGiven = NOT_GIVEN,
+ name: str,
+ metadata: object | NotGiven = NOT_GIVEN,
+ auth_params: Optional[data_source_update_params.NotionDataSourceCreateOrUpdateParamsAuthParams]
+ | Optional[data_source_update_params.LinearDataSourceCreateOrUpdateParamsAuthParams]
+ | 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,
+ ) -> DataSource:
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._put(
f"/v1/data_sources/{data_source_id}",
body=maybe_transform(
{
+ "type": type,
"name": name,
"metadata": metadata,
"auth_params": auth_params,
@@ -327,13 +460,15 @@ def with_streaming_response(self) -> AsyncDataSourcesResourceWithStreamingRespon
"""
return AsyncDataSourcesResourceWithStreamingResponse(self)
+ @overload
async def create(
self,
*,
- type: DataSourceType,
+ type: DataSourceType | NotGiven = NOT_GIVEN,
name: str,
metadata: object | NotGiven = NOT_GIVEN,
- auth_params: Optional[DataSourceOauth2ParamsParam] | NotGiven = NOT_GIVEN,
+ auth_params: Optional[data_source_create_params.NotionDataSourceCreateOrUpdateParamsAuthParams]
+ | 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,
@@ -355,7 +490,8 @@ async def create(
metadata: The metadata of the data source
- auth_params: Authentication parameters for a OAuth data source.
+ auth_params: The authentication parameters of the data source. Notion supports OAuth2 and API
+ key.
extra_headers: Send extra headers
@@ -365,6 +501,67 @@ async def create(
timeout: Override the client-level default timeout for this request, in seconds
"""
+ ...
+
+ @overload
+ async def create(
+ self,
+ *,
+ type: DataSourceType | NotGiven = NOT_GIVEN,
+ name: str,
+ metadata: object | NotGiven = NOT_GIVEN,
+ auth_params: Optional[data_source_create_params.LinearDataSourceCreateOrUpdateParamsAuthParams]
+ | 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,
+ ) -> DataSource:
+ """
+ Create a new data source.
+
+ Args: params: The data source to create.
+
+ Returns: The created data source.
+
+ Args:
+ type: The type of data source to create
+
+ name: The name of the data source
+
+ metadata: The metadata of the data source
+
+ auth_params: Base class for OAuth2 create or update parameters.
+
+ 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
+ """
+ ...
+
+ @required_args(["name"])
+ async def create(
+ self,
+ *,
+ type: DataSourceType | NotGiven = NOT_GIVEN,
+ name: str,
+ metadata: object | NotGiven = NOT_GIVEN,
+ auth_params: Optional[data_source_create_params.NotionDataSourceCreateOrUpdateParamsAuthParams]
+ | Optional[data_source_create_params.LinearDataSourceCreateOrUpdateParamsAuthParams]
+ | 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,
+ ) -> DataSource:
return await self._post(
"/v1/data_sources/",
body=await async_maybe_transform(
@@ -421,13 +618,64 @@ async def retrieve(
cast_to=DataSource,
)
+ @overload
+ async def update(
+ self,
+ data_source_id: str,
+ *,
+ type: DataSourceType | NotGiven = NOT_GIVEN,
+ name: str,
+ metadata: object | NotGiven = NOT_GIVEN,
+ auth_params: Optional[data_source_update_params.NotionDataSourceCreateOrUpdateParamsAuthParams]
+ | 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,
+ ) -> DataSource:
+ """Update a data source.
+
+ Args: data_source_id: The ID of the data source to update.
+
+ params: The data
+ source to update.
+
+ Returns: The updated data source.
+
+ Args:
+ data_source_id: The ID of the data source to update
+
+ type: The type of data source to create
+
+ name: The name of the data source
+
+ metadata: The metadata of the data source
+
+ auth_params: The authentication parameters of the data source. Notion supports OAuth2 and API
+ key.
+
+ 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
+ """
+ ...
+
+ @overload
async def update(
self,
data_source_id: str,
*,
- name: Optional[str] | NotGiven = NOT_GIVEN,
+ type: DataSourceType | NotGiven = NOT_GIVEN,
+ name: str,
metadata: object | NotGiven = NOT_GIVEN,
- auth_params: Optional[DataSourceOauth2ParamsParam] | NotGiven = NOT_GIVEN,
+ auth_params: Optional[data_source_update_params.LinearDataSourceCreateOrUpdateParamsAuthParams]
+ | 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,
@@ -447,11 +695,13 @@ async def update(
Args:
data_source_id: The ID of the data source to update
+ type: The type of data source to create
+
name: The name of the data source
metadata: The metadata of the data source
- auth_params: Authentication parameters for a OAuth data source.
+ auth_params: Base class for OAuth2 create or update parameters.
extra_headers: Send extra headers
@@ -461,12 +711,33 @@ async def update(
timeout: Override the client-level default timeout for this request, in seconds
"""
+ ...
+
+ @required_args(["name"])
+ async def update(
+ self,
+ data_source_id: str,
+ *,
+ type: DataSourceType | NotGiven = NOT_GIVEN,
+ name: str,
+ metadata: object | NotGiven = NOT_GIVEN,
+ auth_params: Optional[data_source_update_params.NotionDataSourceCreateOrUpdateParamsAuthParams]
+ | Optional[data_source_update_params.LinearDataSourceCreateOrUpdateParamsAuthParams]
+ | 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,
+ ) -> DataSource:
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._put(
f"/v1/data_sources/{data_source_id}",
body=await async_maybe_transform(
{
+ "type": type,
"name": name,
"metadata": metadata,
"auth_params": auth_params,
diff --git a/src/mixedbread/resources/vector_stores/files.py b/src/mixedbread/resources/vector_stores/files.py
index 5022d024..76e599e5 100644
--- a/src/mixedbread/resources/vector_stores/files.py
+++ b/src/mixedbread/resources/vector_stores/files.py
@@ -3,7 +3,7 @@
from __future__ import annotations
import functools
-from typing import Any, List, Optional
+from typing import Any, List, Union, Iterable, Optional
import httpx
@@ -50,7 +50,7 @@ def with_streaming_response(self) -> FilesResourceWithStreamingResponse:
def create(
self,
- vector_store_id: str,
+ vector_store_identifier: str,
*,
file_id: str,
metadata: object | NotGiven = NOT_GIVEN,
@@ -65,13 +65,13 @@ def create(
"""
Upload a new file to a vector store for indexing.
- Args: vector_store_id: The ID of the vector store to upload to file: The file to
- upload and index
+ Args: vector_store_identifier: The ID or name of the vector store to upload to
+ file: The file to upload and index
Returns: VectorStoreFile: Details of the uploaded and indexed file
Args:
- vector_store_id: The ID of the vector store
+ vector_store_identifier: The ID or name of the vector store
file_id: ID of the file to add
@@ -87,10 +87,12 @@ def create(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not vector_store_id:
- raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
+ if not vector_store_identifier:
+ raise ValueError(
+ f"Expected a non-empty value for `vector_store_identifier` but received {vector_store_identifier!r}"
+ )
return self._post(
- f"/v1/vector_stores/{vector_store_id}/files",
+ f"/v1/vector_stores/{vector_store_identifier}/files",
body=maybe_transform(
{
"file_id": file_id,
@@ -109,7 +111,7 @@ def retrieve(
self,
file_id: str,
*,
- vector_store_id: str,
+ vector_store_identifier: str,
# 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,
@@ -120,12 +122,13 @@ def retrieve(
"""
Get details of a specific file in a vector store.
- Args: vector_store_id: The ID of the vector store file_id: The ID of the file
+ Args: vector_store_identifier: The ID or name of the vector store file_id: The
+ ID of the file
Returns: VectorStoreFile: Details of the vector store file
Args:
- vector_store_id: The ID of the vector store
+ vector_store_identifier: The ID or name of the vector store
file_id: The ID of the file
@@ -137,12 +140,14 @@ def retrieve(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not vector_store_id:
- raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
+ if not vector_store_identifier:
+ raise ValueError(
+ f"Expected a non-empty value for `vector_store_identifier` but received {vector_store_identifier!r}"
+ )
if not file_id:
raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}")
return self._get(
- f"/v1/vector_stores/{vector_store_id}/files/{file_id}",
+ f"/v1/vector_stores/{vector_store_identifier}/files/{file_id}",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -151,7 +156,7 @@ def retrieve(
def list(
self,
- vector_store_id: str,
+ vector_store_identifier: str,
*,
limit: int | NotGiven = NOT_GIVEN,
offset: int | NotGiven = NOT_GIVEN,
@@ -165,13 +170,13 @@ def list(
"""
List files indexed in a vector store with pagination.
- Args: vector_store_id: The ID of the vector store pagination: Pagination
- parameters
+ Args: vector_store_identifier: The ID or name of the vector store pagination:
+ Pagination parameters
Returns: VectorStoreFileListResponse: Paginated list of vector store files
Args:
- vector_store_id: The ID of the vector store
+ vector_store_identifier: The ID or name of the vector store
limit: Maximum number of items to return per page
@@ -185,10 +190,12 @@ def list(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not vector_store_id:
- raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
+ if not vector_store_identifier:
+ 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_id}/files",
+ f"/v1/vector_stores/{vector_store_identifier}/files",
page=SyncLimitOffset[VectorStoreFile],
options=make_request_options(
extra_headers=extra_headers,
@@ -210,7 +217,7 @@ def delete(
self,
file_id: str,
*,
- vector_store_id: str,
+ vector_store_identifier: str,
# 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,
@@ -221,13 +228,13 @@ def delete(
"""
Delete a file from a vector store.
- Args: vector_store_id: The ID of the vector store file_id: The ID of the file to
- delete
+ Args: vector_store_identifier: The ID or name of the vector store file_id: The
+ ID of the file to delete
Returns: VectorStoreFileDeleted: The deleted file
Args:
- vector_store_id: The ID of the vector store
+ vector_store_identifier: The ID or name of the vector store
file_id: The ID of the file to delete
@@ -239,12 +246,14 @@ def delete(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not vector_store_id:
- raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
+ if not vector_store_identifier:
+ raise ValueError(
+ f"Expected a non-empty value for `vector_store_identifier` but received {vector_store_identifier!r}"
+ )
if not file_id:
raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}")
return self._delete(
- f"/v1/vector_stores/{vector_store_id}/files/{file_id}",
+ f"/v1/vector_stores/{vector_store_identifier}/files/{file_id}",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -255,9 +264,11 @@ def search(
self,
*,
query: str,
- vector_store_ids: List[str],
+ vector_store_identifiers: Optional[List[str]] | NotGiven = NOT_GIVEN,
+ vector_store_ids: Optional[List[str]] | NotGiven = NOT_GIVEN,
top_k: int | NotGiven = NOT_GIVEN,
filters: Optional[file_search_params.Filters] | NotGiven = NOT_GIVEN,
+ file_ids: Union[Iterable[object], List[str], None] | NotGiven = NOT_GIVEN,
search_options: file_search_params.SearchOptions | 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.
@@ -287,12 +298,14 @@ def search(
Args:
query: Search query text
- vector_store_ids: IDs of vector stores to search
+ vector_store_identifiers: IDs or names of vector stores to search
top_k: Number of results to return
filters: Optional filter conditions
+ file_ids: Optional list of file IDs to filter chunks by (inclusion filter)
+
search_options: Search configuration options
extra_headers: Send extra headers
@@ -308,9 +321,11 @@ def search(
body=maybe_transform(
{
"query": query,
+ "vector_store_identifiers": vector_store_identifiers,
"vector_store_ids": vector_store_ids,
"top_k": top_k,
"filters": filters,
+ "file_ids": file_ids,
"search_options": search_options,
},
file_search_params.FileSearchParams,
@@ -450,7 +465,7 @@ def with_streaming_response(self) -> AsyncFilesResourceWithStreamingResponse:
async def create(
self,
- vector_store_id: str,
+ vector_store_identifier: str,
*,
file_id: str,
metadata: object | NotGiven = NOT_GIVEN,
@@ -465,13 +480,13 @@ async def create(
"""
Upload a new file to a vector store for indexing.
- Args: vector_store_id: The ID of the vector store to upload to file: The file to
- upload and index
+ Args: vector_store_identifier: The ID or name of the vector store to upload to
+ file: The file to upload and index
Returns: VectorStoreFile: Details of the uploaded and indexed file
Args:
- vector_store_id: The ID of the vector store
+ vector_store_identifier: The ID or name of the vector store
file_id: ID of the file to add
@@ -487,10 +502,12 @@ async def create(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not vector_store_id:
- raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
+ if not vector_store_identifier:
+ raise ValueError(
+ f"Expected a non-empty value for `vector_store_identifier` but received {vector_store_identifier!r}"
+ )
return await self._post(
- f"/v1/vector_stores/{vector_store_id}/files",
+ f"/v1/vector_stores/{vector_store_identifier}/files",
body=await async_maybe_transform(
{
"file_id": file_id,
@@ -509,7 +526,7 @@ async def retrieve(
self,
file_id: str,
*,
- vector_store_id: str,
+ vector_store_identifier: str,
# 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,
@@ -520,12 +537,13 @@ async def retrieve(
"""
Get details of a specific file in a vector store.
- Args: vector_store_id: The ID of the vector store file_id: The ID of the file
+ Args: vector_store_identifier: The ID or name of the vector store file_id: The
+ ID of the file
Returns: VectorStoreFile: Details of the vector store file
Args:
- vector_store_id: The ID of the vector store
+ vector_store_identifier: The ID or name of the vector store
file_id: The ID of the file
@@ -537,12 +555,14 @@ async def retrieve(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not vector_store_id:
- raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
+ if not vector_store_identifier:
+ raise ValueError(
+ f"Expected a non-empty value for `vector_store_identifier` but received {vector_store_identifier!r}"
+ )
if not file_id:
raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}")
return await self._get(
- f"/v1/vector_stores/{vector_store_id}/files/{file_id}",
+ f"/v1/vector_stores/{vector_store_identifier}/files/{file_id}",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -551,7 +571,7 @@ async def retrieve(
def list(
self,
- vector_store_id: str,
+ vector_store_identifier: str,
*,
limit: int | NotGiven = NOT_GIVEN,
offset: int | NotGiven = NOT_GIVEN,
@@ -565,13 +585,13 @@ def list(
"""
List files indexed in a vector store with pagination.
- Args: vector_store_id: The ID of the vector store pagination: Pagination
- parameters
+ Args: vector_store_identifier: The ID or name of the vector store pagination:
+ Pagination parameters
Returns: VectorStoreFileListResponse: Paginated list of vector store files
Args:
- vector_store_id: The ID of the vector store
+ vector_store_identifier: The ID or name of the vector store
limit: Maximum number of items to return per page
@@ -585,10 +605,12 @@ def list(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not vector_store_id:
- raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
+ if not vector_store_identifier:
+ 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_id}/files",
+ f"/v1/vector_stores/{vector_store_identifier}/files",
page=AsyncLimitOffset[VectorStoreFile],
options=make_request_options(
extra_headers=extra_headers,
@@ -610,7 +632,7 @@ async def delete(
self,
file_id: str,
*,
- vector_store_id: str,
+ vector_store_identifier: str,
# 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,
@@ -621,13 +643,13 @@ async def delete(
"""
Delete a file from a vector store.
- Args: vector_store_id: The ID of the vector store file_id: The ID of the file to
- delete
+ Args: vector_store_identifier: The ID or name of the vector store file_id: The
+ ID of the file to delete
Returns: VectorStoreFileDeleted: The deleted file
Args:
- vector_store_id: The ID of the vector store
+ vector_store_identifier: The ID or name of the vector store
file_id: The ID of the file to delete
@@ -639,12 +661,14 @@ async def delete(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not vector_store_id:
- raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
+ if not vector_store_identifier:
+ raise ValueError(
+ f"Expected a non-empty value for `vector_store_identifier` but received {vector_store_identifier!r}"
+ )
if not file_id:
raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}")
return await self._delete(
- f"/v1/vector_stores/{vector_store_id}/files/{file_id}",
+ f"/v1/vector_stores/{vector_store_identifier}/files/{file_id}",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -655,9 +679,11 @@ async def search(
self,
*,
query: str,
- vector_store_ids: List[str],
+ vector_store_identifiers: Optional[List[str]] | NotGiven = NOT_GIVEN,
+ vector_store_ids: Optional[List[str]] | NotGiven = NOT_GIVEN,
top_k: int | NotGiven = NOT_GIVEN,
filters: Optional[file_search_params.Filters] | NotGiven = NOT_GIVEN,
+ file_ids: Union[Iterable[object], List[str], None] | NotGiven = NOT_GIVEN,
search_options: file_search_params.SearchOptions | 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.
@@ -687,12 +713,14 @@ async def search(
Args:
query: Search query text
- vector_store_ids: IDs of vector stores to search
+ vector_store_identifiers: IDs or names of vector stores to search
top_k: Number of results to return
filters: Optional filter conditions
+ file_ids: Optional list of file IDs to filter chunks by (inclusion filter)
+
search_options: Search configuration options
extra_headers: Send extra headers
@@ -708,9 +736,11 @@ async def search(
body=await async_maybe_transform(
{
"query": query,
+ "vector_store_identifiers": vector_store_identifiers,
"vector_store_ids": vector_store_ids,
"top_k": top_k,
"filters": filters,
+ "file_ids": file_ids,
"search_options": search_options,
},
file_search_params.FileSearchParams,
diff --git a/src/mixedbread/resources/vector_stores/vector_stores.py b/src/mixedbread/resources/vector_stores/vector_stores.py
index 18b25941..2d476dac 100644
--- a/src/mixedbread/resources/vector_stores/vector_stores.py
+++ b/src/mixedbread/resources/vector_stores/vector_stores.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import List, Optional
+from typing import List, Union, Iterable, Optional
import httpx
@@ -129,7 +129,7 @@ def create(
def retrieve(
self,
- vector_store_id: str,
+ vector_store_identifier: str,
*,
# 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.
@@ -139,14 +139,14 @@ def retrieve(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> VectorStore:
"""
- Get a vector store by ID.
+ Get a vector store by ID or name.
- Args: vector_store_id: The ID of the vector store to retrieve.
+ Args: vector_store_identifier: The ID or name of the vector store to retrieve.
Returns: VectorStore: The response containing the vector store details.
Args:
- vector_store_id: The ID of the vector store
+ vector_store_identifier: The ID or name of the vector store
extra_headers: Send extra headers
@@ -156,10 +156,12 @@ def retrieve(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not vector_store_id:
- raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
+ if not vector_store_identifier:
+ raise ValueError(
+ f"Expected a non-empty value for `vector_store_identifier` but received {vector_store_identifier!r}"
+ )
return self._get(
- f"/v1/vector_stores/{vector_store_id}",
+ f"/v1/vector_stores/{vector_store_identifier}",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -168,7 +170,7 @@ def retrieve(
def update(
self,
- vector_store_id: str,
+ vector_store_identifier: str,
*,
name: Optional[str] | NotGiven = NOT_GIVEN,
description: Optional[str] | NotGiven = NOT_GIVEN,
@@ -182,16 +184,16 @@ def update(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> VectorStore:
"""
- Update a vector store by ID.
+ Update a vector store by ID or name.
- Args: vector_store_id: The ID of the vector store to update.
+ Args: vector_store_identifier: The ID or name of the vector store to update.
vector_store_update: VectorStoreCreate object containing the name, description,
and metadata.
Returns: VectorStore: The response containing the updated vector store details.
Args:
- vector_store_id: The ID of the vector store
+ vector_store_identifier: The ID or name of the vector store
name: New name for the vector store
@@ -209,10 +211,12 @@ def update(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not vector_store_id:
- raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
+ if not vector_store_identifier:
+ raise ValueError(
+ f"Expected a non-empty value for `vector_store_identifier` but received {vector_store_identifier!r}"
+ )
return self._put(
- f"/v1/vector_stores/{vector_store_id}",
+ f"/v1/vector_stores/{vector_store_identifier}",
body=maybe_transform(
{
"name": name,
@@ -233,6 +237,7 @@ def list(
*,
limit: int | NotGiven = NOT_GIVEN,
offset: int | NotGiven = NOT_GIVEN,
+ q: Optional[str] | 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,
@@ -241,9 +246,10 @@ def list(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> SyncLimitOffset[VectorStore]:
"""
- List all vector stores.
+ List all vector stores with optional search.
- Args: pagination: The pagination options.
+ Args: pagination: The pagination options. q: Optional search query to filter
+ vector stores.
Returns: VectorStoreListResponse: The list of vector stores.
@@ -252,6 +258,8 @@ def list(
offset: Offset of the first item to return
+ q: Search query for fuzzy matching over name and description fields
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -272,6 +280,7 @@ def list(
{
"limit": limit,
"offset": offset,
+ "q": q,
},
vector_store_list_params.VectorStoreListParams,
),
@@ -281,7 +290,7 @@ def list(
def delete(
self,
- vector_store_id: str,
+ vector_store_identifier: str,
*,
# 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.
@@ -291,14 +300,14 @@ def delete(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> VectorStoreDeleteResponse:
"""
- Delete a vector store by ID.
+ Delete a vector store by ID or name.
- Args: vector_store_id: The ID of the vector store to delete.
+ Args: vector_store_identifier: The ID or name of the vector store to delete.
Returns: VectorStore: The response containing the deleted vector store details.
Args:
- vector_store_id: The ID of the vector store to delete
+ vector_store_identifier: The ID or name of the vector store to delete
extra_headers: Send extra headers
@@ -308,10 +317,12 @@ def delete(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not vector_store_id:
- raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
+ if not vector_store_identifier:
+ raise ValueError(
+ f"Expected a non-empty value for `vector_store_identifier` but received {vector_store_identifier!r}"
+ )
return self._delete(
- f"/v1/vector_stores/{vector_store_id}",
+ f"/v1/vector_stores/{vector_store_identifier}",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -322,9 +333,11 @@ def question_answering(
self,
*,
query: str | NotGiven = NOT_GIVEN,
- vector_store_ids: List[str],
+ vector_store_identifiers: Optional[List[str]] | NotGiven = NOT_GIVEN,
+ vector_store_ids: Optional[List[str]] | NotGiven = NOT_GIVEN,
top_k: int | NotGiven = NOT_GIVEN,
filters: Optional[vector_store_question_answering_params.Filters] | NotGiven = NOT_GIVEN,
+ file_ids: Union[Iterable[object], List[str], None] | NotGiven = NOT_GIVEN,
search_options: VectorStoreChunkSearchOptionsParam | NotGiven = NOT_GIVEN,
stream: bool | NotGiven = NOT_GIVEN,
qa_options: vector_store_question_answering_params.QaOptions | NotGiven = NOT_GIVEN,
@@ -343,12 +356,14 @@ def question_answering(
If not provided, the question will be extracted from the
passed messages.
- vector_store_ids: IDs of vector stores to search
+ vector_store_identifiers: IDs or names of vector stores to search
top_k: Number of results to return
filters: Optional filter conditions
+ file_ids: Optional list of file IDs to filter chunks by (inclusion filter)
+
search_options: Search configuration options
stream: Whether to stream the answer
@@ -368,9 +383,11 @@ def question_answering(
body=maybe_transform(
{
"query": query,
+ "vector_store_identifiers": vector_store_identifiers,
"vector_store_ids": vector_store_ids,
"top_k": top_k,
"filters": filters,
+ "file_ids": file_ids,
"search_options": search_options,
"stream": stream,
"qa_options": qa_options,
@@ -387,9 +404,11 @@ def search(
self,
*,
query: str,
- vector_store_ids: List[str],
+ vector_store_identifiers: Optional[List[str]] | NotGiven = NOT_GIVEN,
+ vector_store_ids: Optional[List[str]] | NotGiven = NOT_GIVEN,
top_k: int | NotGiven = NOT_GIVEN,
filters: Optional[vector_store_search_params.Filters] | NotGiven = NOT_GIVEN,
+ file_ids: Union[Iterable[object], List[str], None] | NotGiven = NOT_GIVEN,
search_options: VectorStoreChunkSearchOptionsParam | 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.
@@ -406,7 +425,9 @@ def search(
relevance-scored results.
Args: search_params: Search configuration including: - query text or
- embeddings - metadata filters - pagination parameters - sorting preferences
+ embeddings - vector_store_ids: List of vector stores to search - file_ids:
+ Optional list of file IDs to filter chunks by (or tuple of list and condition
+ operator) - metadata filters - pagination parameters - sorting preferences
\\__state: API state dependency \\__ctx: Service context dependency
Returns: VectorStoreSearchChunkResponse containing: - List of matched chunks
@@ -418,12 +439,14 @@ def search(
Args:
query: Search query text
- vector_store_ids: IDs of vector stores to search
+ vector_store_identifiers: IDs or names of vector stores to search
top_k: Number of results to return
filters: Optional filter conditions
+ file_ids: Optional list of file IDs to filter chunks by (inclusion filter)
+
search_options: Search configuration options
extra_headers: Send extra headers
@@ -439,9 +462,11 @@ def search(
body=maybe_transform(
{
"query": query,
+ "vector_store_identifiers": vector_store_identifiers,
"vector_store_ids": vector_store_ids,
"top_k": top_k,
"filters": filters,
+ "file_ids": file_ids,
"search_options": search_options,
},
vector_store_search_params.VectorStoreSearchParams,
@@ -539,7 +564,7 @@ async def create(
async def retrieve(
self,
- vector_store_id: str,
+ vector_store_identifier: str,
*,
# 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.
@@ -549,14 +574,14 @@ async def retrieve(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> VectorStore:
"""
- Get a vector store by ID.
+ Get a vector store by ID or name.
- Args: vector_store_id: The ID of the vector store to retrieve.
+ Args: vector_store_identifier: The ID or name of the vector store to retrieve.
Returns: VectorStore: The response containing the vector store details.
Args:
- vector_store_id: The ID of the vector store
+ vector_store_identifier: The ID or name of the vector store
extra_headers: Send extra headers
@@ -566,10 +591,12 @@ async def retrieve(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not vector_store_id:
- raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
+ if not vector_store_identifier:
+ raise ValueError(
+ f"Expected a non-empty value for `vector_store_identifier` but received {vector_store_identifier!r}"
+ )
return await self._get(
- f"/v1/vector_stores/{vector_store_id}",
+ f"/v1/vector_stores/{vector_store_identifier}",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -578,7 +605,7 @@ async def retrieve(
async def update(
self,
- vector_store_id: str,
+ vector_store_identifier: str,
*,
name: Optional[str] | NotGiven = NOT_GIVEN,
description: Optional[str] | NotGiven = NOT_GIVEN,
@@ -592,16 +619,16 @@ async def update(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> VectorStore:
"""
- Update a vector store by ID.
+ Update a vector store by ID or name.
- Args: vector_store_id: The ID of the vector store to update.
+ Args: vector_store_identifier: The ID or name of the vector store to update.
vector_store_update: VectorStoreCreate object containing the name, description,
and metadata.
Returns: VectorStore: The response containing the updated vector store details.
Args:
- vector_store_id: The ID of the vector store
+ vector_store_identifier: The ID or name of the vector store
name: New name for the vector store
@@ -619,10 +646,12 @@ async def update(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not vector_store_id:
- raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
+ if not vector_store_identifier:
+ raise ValueError(
+ f"Expected a non-empty value for `vector_store_identifier` but received {vector_store_identifier!r}"
+ )
return await self._put(
- f"/v1/vector_stores/{vector_store_id}",
+ f"/v1/vector_stores/{vector_store_identifier}",
body=await async_maybe_transform(
{
"name": name,
@@ -643,6 +672,7 @@ def list(
*,
limit: int | NotGiven = NOT_GIVEN,
offset: int | NotGiven = NOT_GIVEN,
+ q: Optional[str] | 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,
@@ -651,9 +681,10 @@ def list(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> AsyncPaginator[VectorStore, AsyncLimitOffset[VectorStore]]:
"""
- List all vector stores.
+ List all vector stores with optional search.
- Args: pagination: The pagination options.
+ Args: pagination: The pagination options. q: Optional search query to filter
+ vector stores.
Returns: VectorStoreListResponse: The list of vector stores.
@@ -662,6 +693,8 @@ def list(
offset: Offset of the first item to return
+ q: Search query for fuzzy matching over name and description fields
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -682,6 +715,7 @@ def list(
{
"limit": limit,
"offset": offset,
+ "q": q,
},
vector_store_list_params.VectorStoreListParams,
),
@@ -691,7 +725,7 @@ def list(
async def delete(
self,
- vector_store_id: str,
+ vector_store_identifier: str,
*,
# 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.
@@ -701,14 +735,14 @@ async def delete(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> VectorStoreDeleteResponse:
"""
- Delete a vector store by ID.
+ Delete a vector store by ID or name.
- Args: vector_store_id: The ID of the vector store to delete.
+ Args: vector_store_identifier: The ID or name of the vector store to delete.
Returns: VectorStore: The response containing the deleted vector store details.
Args:
- vector_store_id: The ID of the vector store to delete
+ vector_store_identifier: The ID or name of the vector store to delete
extra_headers: Send extra headers
@@ -718,10 +752,12 @@ async def delete(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not vector_store_id:
- raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
+ if not vector_store_identifier:
+ raise ValueError(
+ f"Expected a non-empty value for `vector_store_identifier` but received {vector_store_identifier!r}"
+ )
return await self._delete(
- f"/v1/vector_stores/{vector_store_id}",
+ f"/v1/vector_stores/{vector_store_identifier}",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -732,9 +768,11 @@ async def question_answering(
self,
*,
query: str | NotGiven = NOT_GIVEN,
- vector_store_ids: List[str],
+ vector_store_identifiers: Optional[List[str]] | NotGiven = NOT_GIVEN,
+ vector_store_ids: Optional[List[str]] | NotGiven = NOT_GIVEN,
top_k: int | NotGiven = NOT_GIVEN,
filters: Optional[vector_store_question_answering_params.Filters] | NotGiven = NOT_GIVEN,
+ file_ids: Union[Iterable[object], List[str], None] | NotGiven = NOT_GIVEN,
search_options: VectorStoreChunkSearchOptionsParam | NotGiven = NOT_GIVEN,
stream: bool | NotGiven = NOT_GIVEN,
qa_options: vector_store_question_answering_params.QaOptions | NotGiven = NOT_GIVEN,
@@ -753,12 +791,14 @@ async def question_answering(
If not provided, the question will be extracted from the
passed messages.
- vector_store_ids: IDs of vector stores to search
+ vector_store_identifiers: IDs or names of vector stores to search
top_k: Number of results to return
filters: Optional filter conditions
+ file_ids: Optional list of file IDs to filter chunks by (inclusion filter)
+
search_options: Search configuration options
stream: Whether to stream the answer
@@ -778,9 +818,11 @@ async def question_answering(
body=await async_maybe_transform(
{
"query": query,
+ "vector_store_identifiers": vector_store_identifiers,
"vector_store_ids": vector_store_ids,
"top_k": top_k,
"filters": filters,
+ "file_ids": file_ids,
"search_options": search_options,
"stream": stream,
"qa_options": qa_options,
@@ -797,9 +839,11 @@ async def search(
self,
*,
query: str,
- vector_store_ids: List[str],
+ vector_store_identifiers: Optional[List[str]] | NotGiven = NOT_GIVEN,
+ vector_store_ids: Optional[List[str]] | NotGiven = NOT_GIVEN,
top_k: int | NotGiven = NOT_GIVEN,
filters: Optional[vector_store_search_params.Filters] | NotGiven = NOT_GIVEN,
+ file_ids: Union[Iterable[object], List[str], None] | NotGiven = NOT_GIVEN,
search_options: VectorStoreChunkSearchOptionsParam | 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.
@@ -816,7 +860,9 @@ async def search(
relevance-scored results.
Args: search_params: Search configuration including: - query text or
- embeddings - metadata filters - pagination parameters - sorting preferences
+ embeddings - vector_store_ids: List of vector stores to search - file_ids:
+ Optional list of file IDs to filter chunks by (or tuple of list and condition
+ operator) - metadata filters - pagination parameters - sorting preferences
\\__state: API state dependency \\__ctx: Service context dependency
Returns: VectorStoreSearchChunkResponse containing: - List of matched chunks
@@ -828,12 +874,14 @@ async def search(
Args:
query: Search query text
- vector_store_ids: IDs of vector stores to search
+ vector_store_identifiers: IDs or names of vector stores to search
top_k: Number of results to return
filters: Optional filter conditions
+ file_ids: Optional list of file IDs to filter chunks by (inclusion filter)
+
search_options: Search configuration options
extra_headers: Send extra headers
@@ -849,9 +897,11 @@ async def search(
body=await async_maybe_transform(
{
"query": query,
+ "vector_store_identifiers": vector_store_identifiers,
"vector_store_ids": vector_store_ids,
"top_k": top_k,
"filters": filters,
+ "file_ids": file_ids,
"search_options": search_options,
},
vector_store_search_params.VectorStoreSearchParams,
diff --git a/src/mixedbread/types/__init__.py b/src/mixedbread/types/__init__.py
index 56f206a5..4b299a86 100644
--- a/src/mixedbread/types/__init__.py
+++ b/src/mixedbread/types/__init__.py
@@ -44,7 +44,6 @@
from .scored_video_url_input_chunk import ScoredVideoURLInputChunk as ScoredVideoURLInputChunk
from .vector_store_delete_response import VectorStoreDeleteResponse as VectorStoreDeleteResponse
from .vector_store_search_response import VectorStoreSearchResponse as VectorStoreSearchResponse
-from .data_source_oauth2_params_param import DataSourceOauth2ParamsParam as DataSourceOauth2ParamsParam
from .vector_store_question_answering_params import (
VectorStoreQuestionAnsweringParams as VectorStoreQuestionAnsweringParams,
)
diff --git a/src/mixedbread/types/data_source.py b/src/mixedbread/types/data_source.py
index d02682e1..eefb4d3d 100644
--- a/src/mixedbread/types/data_source.py
+++ b/src/mixedbread/types/data_source.py
@@ -1,14 +1,27 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Optional
+from typing import Union, Optional
from datetime import datetime
-from typing_extensions import Literal
+from typing_extensions import Literal, Annotated, TypeAlias
+from .._utils import PropertyInfo
from .._models import BaseModel
from .data_source_type import DataSourceType
from .data_source_oauth2_params import DataSourceOauth2Params
-__all__ = ["DataSource"]
+__all__ = ["DataSource", "AuthParams", "AuthParamsDataSourceAPIKeyParams"]
+
+
+class AuthParamsDataSourceAPIKeyParams(BaseModel):
+ type: Optional[Literal["api_key"]] = None
+
+ api_key: str
+ """The API key"""
+
+
+AuthParams: TypeAlias = Annotated[
+ Union[DataSourceOauth2Params, AuthParamsDataSourceAPIKeyParams, None], PropertyInfo(discriminator="type")
+]
class DataSource(BaseModel):
@@ -30,8 +43,8 @@ class DataSource(BaseModel):
metadata: object
"""The metadata of the data source"""
- auth_params: Optional[DataSourceOauth2Params] = None
- """Authentication parameters for a OAuth data source."""
+ auth_params: Optional[AuthParams] = None
+ """Authentication parameters"""
object: Optional[Literal["data_source"]] = None
"""The type of the object"""
diff --git a/src/mixedbread/types/data_source_create_params.py b/src/mixedbread/types/data_source_create_params.py
index af01ebdd..e9794cdb 100644
--- a/src/mixedbread/types/data_source_create_params.py
+++ b/src/mixedbread/types/data_source_create_params.py
@@ -2,17 +2,24 @@
from __future__ import annotations
-from typing import Optional
-from typing_extensions import Required, TypedDict
+from typing import Union, Optional
+from typing_extensions import Literal, Required, TypeAlias, TypedDict
from .data_source_type import DataSourceType
-from .data_source_oauth2_params_param import DataSourceOauth2ParamsParam
-__all__ = ["DataSourceCreateParams"]
+__all__ = [
+ "DataSourceCreateParams",
+ "NotionDataSourceCreateOrUpdateParams",
+ "NotionDataSourceCreateOrUpdateParamsAuthParams",
+ "NotionDataSourceCreateOrUpdateParamsAuthParamsOAuth2CreateOrUpdateParams",
+ "NotionDataSourceCreateOrUpdateParamsAuthParamsAPIKeyCreateOrUpdateParams",
+ "LinearDataSourceCreateOrUpdateParams",
+ "LinearDataSourceCreateOrUpdateParamsAuthParams",
+]
-class DataSourceCreateParams(TypedDict, total=False):
- type: Required[DataSourceType]
+class NotionDataSourceCreateOrUpdateParams(TypedDict, total=False):
+ type: DataSourceType
"""The type of data source to create"""
name: Required[str]
@@ -21,5 +28,46 @@ class DataSourceCreateParams(TypedDict, total=False):
metadata: object
"""The metadata of the data source"""
- auth_params: Optional[DataSourceOauth2ParamsParam]
- """Authentication parameters for a OAuth data source."""
+ auth_params: Optional[NotionDataSourceCreateOrUpdateParamsAuthParams]
+ """The authentication parameters of the data source.
+
+ Notion supports OAuth2 and API key.
+ """
+
+
+class NotionDataSourceCreateOrUpdateParamsAuthParamsOAuth2CreateOrUpdateParams(TypedDict, total=False):
+ type: Literal["oauth2"]
+
+
+class NotionDataSourceCreateOrUpdateParamsAuthParamsAPIKeyCreateOrUpdateParams(TypedDict, total=False):
+ type: Literal["api_key"]
+
+ api_key: Required[str]
+ """The API key"""
+
+
+NotionDataSourceCreateOrUpdateParamsAuthParams: TypeAlias = Union[
+ NotionDataSourceCreateOrUpdateParamsAuthParamsOAuth2CreateOrUpdateParams,
+ NotionDataSourceCreateOrUpdateParamsAuthParamsAPIKeyCreateOrUpdateParams,
+]
+
+
+class LinearDataSourceCreateOrUpdateParams(TypedDict, total=False):
+ type: DataSourceType
+ """The type of data source to create"""
+
+ name: Required[str]
+ """The name of the data source"""
+
+ metadata: object
+ """The metadata of the data source"""
+
+ auth_params: Optional[LinearDataSourceCreateOrUpdateParamsAuthParams]
+ """Base class for OAuth2 create or update parameters."""
+
+
+class LinearDataSourceCreateOrUpdateParamsAuthParams(TypedDict, total=False):
+ type: Literal["oauth2"]
+
+
+DataSourceCreateParams: TypeAlias = Union[NotionDataSourceCreateOrUpdateParams, LinearDataSourceCreateOrUpdateParams]
diff --git a/src/mixedbread/types/data_source_oauth2_params.py b/src/mixedbread/types/data_source_oauth2_params.py
index 5cda3db5..3e9c8a90 100644
--- a/src/mixedbread/types/data_source_oauth2_params.py
+++ b/src/mixedbread/types/data_source_oauth2_params.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Optional
+from typing import Dict, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -15,16 +15,7 @@ class DataSourceOauth2Params(BaseModel):
created_at: Optional[datetime] = None
"""The timestamp when the OAuth2 credentials were created"""
- client_id: str
- """The OAuth2 client ID"""
-
- client_secret: str
- """The OAuth2 client secret"""
-
- redirect_uri: str
- """The OAuth2 redirect URI"""
-
- scope: str
+ scope: Optional[str] = None
"""The OAuth2 scope"""
access_token: Optional[str] = None
@@ -38,3 +29,6 @@ class DataSourceOauth2Params(BaseModel):
expires_on: Optional[datetime] = None
"""The OAuth2 token expiration timestamp"""
+
+ additional_params: Optional[Dict[str, object]] = None
+ """Additional parameters for the OAuth2 flow"""
diff --git a/src/mixedbread/types/data_source_oauth2_params_param.py b/src/mixedbread/types/data_source_oauth2_params_param.py
deleted file mode 100644
index 72ff4b56..00000000
--- a/src/mixedbread/types/data_source_oauth2_params_param.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Union, Optional
-from datetime import datetime
-from typing_extensions import Literal, Required, Annotated, TypedDict
-
-from .._utils import PropertyInfo
-
-__all__ = ["DataSourceOauth2ParamsParam"]
-
-
-class DataSourceOauth2ParamsParam(TypedDict, total=False):
- type: Literal["oauth2"]
-
- created_at: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]
- """The timestamp when the OAuth2 credentials were created"""
-
- client_id: Required[str]
- """The OAuth2 client ID"""
-
- client_secret: Required[str]
- """The OAuth2 client secret"""
-
- redirect_uri: Required[str]
- """The OAuth2 redirect URI"""
-
- scope: Required[str]
- """The OAuth2 scope"""
-
- access_token: Optional[str]
- """The OAuth2 access token"""
-
- refresh_token: Optional[str]
- """The OAuth2 refresh token"""
-
- token_type: Optional[str]
- """The OAuth2 token type"""
-
- expires_on: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")]
- """The OAuth2 token expiration timestamp"""
diff --git a/src/mixedbread/types/data_source_update_params.py b/src/mixedbread/types/data_source_update_params.py
index 609704a0..23d34c4a 100644
--- a/src/mixedbread/types/data_source_update_params.py
+++ b/src/mixedbread/types/data_source_update_params.py
@@ -2,20 +2,72 @@
from __future__ import annotations
-from typing import Optional
-from typing_extensions import TypedDict
+from typing import Union, Optional
+from typing_extensions import Literal, Required, TypeAlias, TypedDict
-from .data_source_oauth2_params_param import DataSourceOauth2ParamsParam
+from .data_source_type import DataSourceType
-__all__ = ["DataSourceUpdateParams"]
+__all__ = [
+ "DataSourceUpdateParams",
+ "NotionDataSourceCreateOrUpdateParams",
+ "NotionDataSourceCreateOrUpdateParamsAuthParams",
+ "NotionDataSourceCreateOrUpdateParamsAuthParamsOAuth2CreateOrUpdateParams",
+ "NotionDataSourceCreateOrUpdateParamsAuthParamsAPIKeyCreateOrUpdateParams",
+ "LinearDataSourceCreateOrUpdateParams",
+ "LinearDataSourceCreateOrUpdateParamsAuthParams",
+]
-class DataSourceUpdateParams(TypedDict, total=False):
- name: Optional[str]
+class NotionDataSourceCreateOrUpdateParams(TypedDict, total=False):
+ type: DataSourceType
+ """The type of data source to create"""
+
+ name: Required[str]
"""The name of the data source"""
metadata: object
"""The metadata of the data source"""
- auth_params: Optional[DataSourceOauth2ParamsParam]
- """Authentication parameters for a OAuth data source."""
+ auth_params: Optional[NotionDataSourceCreateOrUpdateParamsAuthParams]
+ """The authentication parameters of the data source.
+
+ Notion supports OAuth2 and API key.
+ """
+
+
+class NotionDataSourceCreateOrUpdateParamsAuthParamsOAuth2CreateOrUpdateParams(TypedDict, total=False):
+ type: Literal["oauth2"]
+
+
+class NotionDataSourceCreateOrUpdateParamsAuthParamsAPIKeyCreateOrUpdateParams(TypedDict, total=False):
+ type: Literal["api_key"]
+
+ api_key: Required[str]
+ """The API key"""
+
+
+NotionDataSourceCreateOrUpdateParamsAuthParams: TypeAlias = Union[
+ NotionDataSourceCreateOrUpdateParamsAuthParamsOAuth2CreateOrUpdateParams,
+ NotionDataSourceCreateOrUpdateParamsAuthParamsAPIKeyCreateOrUpdateParams,
+]
+
+
+class LinearDataSourceCreateOrUpdateParams(TypedDict, total=False):
+ type: DataSourceType
+ """The type of data source to create"""
+
+ name: Required[str]
+ """The name of the data source"""
+
+ metadata: object
+ """The metadata of the data source"""
+
+ auth_params: Optional[LinearDataSourceCreateOrUpdateParamsAuthParams]
+ """Base class for OAuth2 create or update parameters."""
+
+
+class LinearDataSourceCreateOrUpdateParamsAuthParams(TypedDict, total=False):
+ type: Literal["oauth2"]
+
+
+DataSourceUpdateParams: TypeAlias = Union[NotionDataSourceCreateOrUpdateParams, LinearDataSourceCreateOrUpdateParams]
diff --git a/src/mixedbread/types/data_sources/connector_create_params.py b/src/mixedbread/types/data_sources/connector_create_params.py
index 6b1f8ed4..43c23c67 100644
--- a/src/mixedbread/types/data_sources/connector_create_params.py
+++ b/src/mixedbread/types/data_sources/connector_create_params.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import Optional
+from typing import Union
from typing_extensions import Required, TypedDict
__all__ = ["ConnectorCreateParams"]
@@ -21,5 +21,12 @@ class ConnectorCreateParams(TypedDict, total=False):
metadata: object
"""The metadata of the connector"""
- polling_interval: Optional[str]
- """The polling interval of the connector"""
+ polling_interval: Union[int, str, None]
+ """Polling interval for the connector.
+
+ Defaults to 30 minutes if not specified. Can be provided as:
+
+ - int: Number of seconds (e.g., 1800 for 30 minutes)
+ - str: Duration string (e.g., '30m', '1h', '2d') or ISO 8601 format (e.g.,
+ 'PT30M', 'P1D') Valid range: 15 seconds to 30 days
+ """
diff --git a/src/mixedbread/types/data_sources/connector_update_params.py b/src/mixedbread/types/data_sources/connector_update_params.py
index 80434be2..7e0d112b 100644
--- a/src/mixedbread/types/data_sources/connector_update_params.py
+++ b/src/mixedbread/types/data_sources/connector_update_params.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import Dict, Optional
+from typing import Dict, Union, Optional
from typing_extensions import Required, TypedDict
__all__ = ["ConnectorUpdateParams"]
@@ -21,5 +21,12 @@ class ConnectorUpdateParams(TypedDict, total=False):
trigger_sync: Optional[bool]
"""Whether the connector should be synced after update"""
- polling_interval: Optional[str]
- """The polling interval of the connector"""
+ polling_interval: Union[int, str, None]
+ """Polling interval for the connector.
+
+ Defaults to 30 minutes if not specified. Can be provided as:
+
+ - int: Number of seconds (e.g., 1800 for 30 minutes)
+ - str: Duration string (e.g., '30m', '1h', '2d') or ISO 8601 format (e.g.,
+ 'PT30M', 'P1D') Valid range: 15 seconds to 30 days
+ """
diff --git a/src/mixedbread/types/extractions/image_url_input_param.py b/src/mixedbread/types/extractions/image_url_input_param.py
index 6c361176..a4480f76 100644
--- a/src/mixedbread/types/extractions/image_url_input_param.py
+++ b/src/mixedbread/types/extractions/image_url_input_param.py
@@ -11,6 +11,9 @@ class ImageURL(TypedDict, total=False):
url: Required[str]
"""The image URL. Can be either a URL or a Data URI."""
+ format: str
+ """The image format/mimetype"""
+
class ImageURLInputParam(TypedDict, total=False):
type: Literal["image_url"]
diff --git a/src/mixedbread/types/scored_image_url_input_chunk.py b/src/mixedbread/types/scored_image_url_input_chunk.py
index ec6ba9dd..f160a46d 100644
--- a/src/mixedbread/types/scored_image_url_input_chunk.py
+++ b/src/mixedbread/types/scored_image_url_input_chunk.py
@@ -12,6 +12,9 @@ class ImageURL(BaseModel):
url: str
"""The image URL. Can be either a URL or a Data URI."""
+ format: Optional[str] = None
+ """The image format/mimetype"""
+
class ScoredImageURLInputChunk(BaseModel):
chunk_index: int
diff --git a/src/mixedbread/types/vector_store.py b/src/mixedbread/types/vector_store.py
index 65cb0ede..c2ab8879 100644
--- a/src/mixedbread/types/vector_store.py
+++ b/src/mixedbread/types/vector_store.py
@@ -11,6 +11,9 @@
class FileCounts(BaseModel):
+ pending: Optional[int] = None
+ """Number of files waiting to be processed"""
+
in_progress: Optional[int] = None
"""Number of files currently being processed"""
diff --git a/src/mixedbread/types/vector_store_chunk_search_options_param.py b/src/mixedbread/types/vector_store_chunk_search_options_param.py
index a2396bec..f5fb8437 100644
--- a/src/mixedbread/types/vector_store_chunk_search_options_param.py
+++ b/src/mixedbread/types/vector_store_chunk_search_options_param.py
@@ -2,9 +2,27 @@
from __future__ import annotations
-from typing_extensions import TypedDict
+from typing import List, Union, Optional
+from typing_extensions import TypeAlias, TypedDict
-__all__ = ["VectorStoreChunkSearchOptionsParam"]
+__all__ = ["VectorStoreChunkSearchOptionsParam", "Rerank", "RerankRerankConfig"]
+
+
+class RerankRerankConfig(TypedDict, total=False):
+ model: str
+ """The name of the reranking model"""
+
+ with_metadata: Union[bool, List[str]]
+ """Whether to include metadata in the reranked results"""
+
+ top_k: Optional[int]
+ """Maximum number of results to return after reranking.
+
+ If None, returns all reranked results.
+ """
+
+
+Rerank: TypeAlias = Union[bool, RerankRerankConfig]
class VectorStoreChunkSearchOptionsParam(TypedDict, total=False):
@@ -14,5 +32,8 @@ class VectorStoreChunkSearchOptionsParam(TypedDict, total=False):
rewrite_query: bool
"""Whether to rewrite the query"""
+ rerank: Optional[Rerank]
+ """Whether to rerank results and optional reranking configuration"""
+
return_metadata: bool
"""Whether to return file metadata"""
diff --git a/src/mixedbread/types/vector_store_list_params.py b/src/mixedbread/types/vector_store_list_params.py
index 39225421..4f649424 100644
--- a/src/mixedbread/types/vector_store_list_params.py
+++ b/src/mixedbread/types/vector_store_list_params.py
@@ -2,6 +2,7 @@
from __future__ import annotations
+from typing import Optional
from typing_extensions import TypedDict
__all__ = ["VectorStoreListParams"]
@@ -13,3 +14,6 @@ class VectorStoreListParams(TypedDict, total=False):
offset: int
"""Offset of the first item to return"""
+
+ q: Optional[str]
+ """Search query for fuzzy matching over name and description fields"""
diff --git a/src/mixedbread/types/vector_store_question_answering_params.py b/src/mixedbread/types/vector_store_question_answering_params.py
index abb7919b..b34189b3 100644
--- a/src/mixedbread/types/vector_store_question_answering_params.py
+++ b/src/mixedbread/types/vector_store_question_answering_params.py
@@ -3,7 +3,7 @@
from __future__ import annotations
from typing import List, Union, Iterable, Optional
-from typing_extensions import Required, TypeAlias, TypedDict
+from typing_extensions import TypeAlias, TypedDict
from .shared_params.search_filter_condition import SearchFilterCondition
from .vector_store_chunk_search_options_param import VectorStoreChunkSearchOptionsParam
@@ -18,8 +18,10 @@ class VectorStoreQuestionAnsweringParams(TypedDict, total=False):
If not provided, the question will be extracted from the passed messages.
"""
- vector_store_ids: Required[List[str]]
- """IDs of vector stores to search"""
+ vector_store_identifiers: Optional[List[str]]
+ """IDs or names of vector stores to search"""
+
+ vector_store_ids: Optional[List[str]]
top_k: int
"""Number of results to return"""
@@ -27,6 +29,9 @@ class VectorStoreQuestionAnsweringParams(TypedDict, total=False):
filters: Optional[Filters]
"""Optional filter conditions"""
+ file_ids: Union[Iterable[object], List[str], None]
+ """Optional list of file IDs to filter chunks by (inclusion filter)"""
+
search_options: VectorStoreChunkSearchOptionsParam
"""Search configuration options"""
diff --git a/src/mixedbread/types/vector_store_search_params.py b/src/mixedbread/types/vector_store_search_params.py
index e0edc1bb..48fc21e1 100644
--- a/src/mixedbread/types/vector_store_search_params.py
+++ b/src/mixedbread/types/vector_store_search_params.py
@@ -15,8 +15,10 @@ class VectorStoreSearchParams(TypedDict, total=False):
query: Required[str]
"""Search query text"""
- vector_store_ids: Required[List[str]]
- """IDs of vector stores to search"""
+ vector_store_identifiers: Optional[List[str]]
+ """IDs or names of vector stores to search"""
+
+ vector_store_ids: Optional[List[str]]
top_k: int
"""Number of results to return"""
@@ -24,6 +26,9 @@ class VectorStoreSearchParams(TypedDict, total=False):
filters: Optional[Filters]
"""Optional filter conditions"""
+ file_ids: Union[Iterable[object], List[str], None]
+ """Optional list of file IDs to filter chunks by (inclusion filter)"""
+
search_options: VectorStoreChunkSearchOptionsParam
"""Search configuration options"""
diff --git a/src/mixedbread/types/vector_stores/file_search_params.py b/src/mixedbread/types/vector_stores/file_search_params.py
index c34d7611..2844c28a 100644
--- a/src/mixedbread/types/vector_stores/file_search_params.py
+++ b/src/mixedbread/types/vector_stores/file_search_params.py
@@ -7,15 +7,24 @@
from ..shared_params.search_filter_condition import SearchFilterCondition
-__all__ = ["FileSearchParams", "Filters", "FiltersUnionMember2", "SearchOptions"]
+__all__ = [
+ "FileSearchParams",
+ "Filters",
+ "FiltersUnionMember2",
+ "SearchOptions",
+ "SearchOptionsRerank",
+ "SearchOptionsRerankRerankConfig",
+]
class FileSearchParams(TypedDict, total=False):
query: Required[str]
"""Search query text"""
- vector_store_ids: Required[List[str]]
- """IDs of vector stores to search"""
+ vector_store_identifiers: Optional[List[str]]
+ """IDs or names of vector stores to search"""
+
+ vector_store_ids: Optional[List[str]]
top_k: int
"""Number of results to return"""
@@ -23,6 +32,9 @@ class FileSearchParams(TypedDict, total=False):
filters: Optional[Filters]
"""Optional filter conditions"""
+ file_ids: Union[Iterable[object], List[str], None]
+ """Optional list of file IDs to filter chunks by (inclusion filter)"""
+
search_options: SearchOptions
"""Search configuration options"""
@@ -32,6 +44,23 @@ class FileSearchParams(TypedDict, total=False):
Filters: TypeAlias = Union["SearchFilter", SearchFilterCondition, Iterable[FiltersUnionMember2]]
+class SearchOptionsRerankRerankConfig(TypedDict, total=False):
+ model: str
+ """The name of the reranking model"""
+
+ with_metadata: Union[bool, List[str]]
+ """Whether to include metadata in the reranked results"""
+
+ top_k: Optional[int]
+ """Maximum number of results to return after reranking.
+
+ If None, returns all reranked results.
+ """
+
+
+SearchOptionsRerank: TypeAlias = Union[bool, SearchOptionsRerankRerankConfig]
+
+
class SearchOptions(TypedDict, total=False):
score_threshold: float
"""Minimum similarity score threshold"""
@@ -39,6 +68,9 @@ class SearchOptions(TypedDict, total=False):
rewrite_query: bool
"""Whether to rewrite the query"""
+ rerank: Optional[SearchOptionsRerank]
+ """Whether to rerank results and optional reranking configuration"""
+
return_metadata: bool
"""Whether to return file metadata"""
diff --git a/src/mixedbread/types/vector_stores/scored_vector_store_file.py b/src/mixedbread/types/vector_stores/scored_vector_store_file.py
index 7c702c1c..919dffec 100644
--- a/src/mixedbread/types/vector_stores/scored_vector_store_file.py
+++ b/src/mixedbread/types/vector_stores/scored_vector_store_file.py
@@ -29,7 +29,7 @@ class ScoredVectorStoreFile(BaseModel):
metadata: Optional[object] = None
"""Optional file metadata"""
- status: Optional[str] = None
+ status: Optional[Literal["pending", "in_progress", "cancelled", "completed", "failed"]] = None
"""Processing status of the file"""
last_error: Optional[object] = None
diff --git a/src/mixedbread/types/vector_stores/vector_store_file.py b/src/mixedbread/types/vector_stores/vector_store_file.py
index 39bdb685..d6e5efda 100644
--- a/src/mixedbread/types/vector_stores/vector_store_file.py
+++ b/src/mixedbread/types/vector_stores/vector_store_file.py
@@ -19,7 +19,7 @@ class VectorStoreFile(BaseModel):
metadata: Optional[object] = None
"""Optional file metadata"""
- status: Optional[str] = None
+ status: Optional[Literal["pending", "in_progress", "cancelled", "completed", "failed"]] = None
"""Processing status of the file"""
last_error: Optional[object] = None
diff --git a/tests/api_resources/data_sources/test_connectors.py b/tests/api_resources/data_sources/test_connectors.py
index f25e9ce0..fb95955d 100644
--- a/tests/api_resources/data_sources/test_connectors.py
+++ b/tests/api_resources/data_sources/test_connectors.py
@@ -37,7 +37,7 @@ def test_method_create_with_all_params(self, client: Mixedbread) -> None:
name="name",
trigger_sync=True,
metadata={},
- polling_interval="polling_interval",
+ polling_interval=1800,
)
assert_matches_type(DataSourceConnector, connector, path=["response"])
@@ -139,7 +139,7 @@ def test_method_update_with_all_params(self, client: Mixedbread) -> None:
name="name",
metadata={"foo": "bar"},
trigger_sync=True,
- polling_interval="polling_interval",
+ polling_interval=1800,
)
assert_matches_type(DataSourceConnector, connector, path=["response"])
@@ -298,7 +298,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncMixedbread
name="name",
trigger_sync=True,
metadata={},
- polling_interval="polling_interval",
+ polling_interval=1800,
)
assert_matches_type(DataSourceConnector, connector, path=["response"])
@@ -400,7 +400,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncMixedbread
name="name",
metadata={"foo": "bar"},
trigger_sync=True,
- polling_interval="polling_interval",
+ polling_interval=1800,
)
assert_matches_type(DataSourceConnector, connector, path=["response"])
diff --git a/tests/api_resources/test_chat.py b/tests/api_resources/test_chat.py
deleted file mode 100644
index 65341369..00000000
--- a/tests/api_resources/test_chat.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import pytest
-
-from mixedbread import Mixedbread, AsyncMixedbread
-from tests.utils import assert_matches_type
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestChat:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- def test_method_create_completion(self, client: Mixedbread) -> None:
- chat = client.chat.create_completion()
- assert_matches_type(object, chat, path=["response"])
-
- @parametrize
- def test_raw_response_create_completion(self, client: Mixedbread) -> None:
- response = client.chat.with_raw_response.create_completion()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- chat = response.parse()
- assert_matches_type(object, chat, path=["response"])
-
- @parametrize
- def test_streaming_response_create_completion(self, client: Mixedbread) -> None:
- with client.chat.with_streaming_response.create_completion() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- chat = response.parse()
- assert_matches_type(object, chat, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
-
-class TestAsyncChat:
- parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- async def test_method_create_completion(self, async_client: AsyncMixedbread) -> None:
- chat = await async_client.chat.create_completion()
- assert_matches_type(object, chat, path=["response"])
-
- @parametrize
- async def test_raw_response_create_completion(self, async_client: AsyncMixedbread) -> None:
- response = await async_client.chat.with_raw_response.create_completion()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- chat = await response.parse()
- assert_matches_type(object, chat, path=["response"])
-
- @parametrize
- async def test_streaming_response_create_completion(self, async_client: AsyncMixedbread) -> None:
- async with async_client.chat.with_streaming_response.create_completion() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- chat = await response.parse()
- assert_matches_type(object, chat, 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 be95dcb7..28f502e2 100644
--- a/tests/api_resources/test_data_sources.py
+++ b/tests/api_resources/test_data_sources.py
@@ -13,7 +13,6 @@
DataSource,
DataSourceDeleteResponse,
)
-from mixedbread._utils import parse_datetime
from mixedbread.pagination import SyncLimitOffset, AsyncLimitOffset
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -23,38 +22,25 @@ class TestDataSources:
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
@parametrize
- def test_method_create(self, client: Mixedbread) -> None:
+ def test_method_create_overload_1(self, client: Mixedbread) -> None:
data_source = client.data_sources.create(
- type="notion",
name="name",
)
assert_matches_type(DataSource, data_source, path=["response"])
@parametrize
- def test_method_create_with_all_params(self, client: Mixedbread) -> None:
+ def test_method_create_with_all_params_overload_1(self, client: Mixedbread) -> None:
data_source = client.data_sources.create(
type="notion",
name="name",
metadata={},
- auth_params={
- "type": "oauth2",
- "created_at": parse_datetime("2019-12-27T18:11:19.117Z"),
- "client_id": "client_id",
- "client_secret": "client_secret",
- "redirect_uri": "redirect_uri",
- "scope": "scope",
- "access_token": "access_token",
- "refresh_token": "refresh_token",
- "token_type": "token_type",
- "expires_on": parse_datetime("2019-12-27T18:11:19.117Z"),
- },
+ auth_params={"type": "oauth2"},
)
assert_matches_type(DataSource, data_source, path=["response"])
@parametrize
- def test_raw_response_create(self, client: Mixedbread) -> None:
+ def test_raw_response_create_overload_1(self, client: Mixedbread) -> None:
response = client.data_sources.with_raw_response.create(
- type="notion",
name="name",
)
@@ -64,10 +50,50 @@ def test_raw_response_create(self, client: Mixedbread) -> None:
assert_matches_type(DataSource, data_source, path=["response"])
@parametrize
- def test_streaming_response_create(self, client: Mixedbread) -> None:
+ def test_streaming_response_create_overload_1(self, client: Mixedbread) -> None:
with client.data_sources.with_streaming_response.create(
+ name="name",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ data_source = response.parse()
+ assert_matches_type(DataSource, data_source, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_create_overload_2(self, client: Mixedbread) -> None:
+ data_source = client.data_sources.create(
+ name="name",
+ )
+ assert_matches_type(DataSource, data_source, path=["response"])
+
+ @parametrize
+ def test_method_create_with_all_params_overload_2(self, client: Mixedbread) -> None:
+ data_source = client.data_sources.create(
type="notion",
name="name",
+ metadata={},
+ auth_params={"type": "oauth2"},
+ )
+ assert_matches_type(DataSource, data_source, path=["response"])
+
+ @parametrize
+ def test_raw_response_create_overload_2(self, client: Mixedbread) -> None:
+ response = client.data_sources.with_raw_response.create(
+ name="name",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ data_source = response.parse()
+ assert_matches_type(DataSource, data_source, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create_overload_2(self, client: Mixedbread) -> None:
+ with client.data_sources.with_streaming_response.create(
+ name="name",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -116,37 +142,29 @@ def test_path_params_retrieve(self, client: Mixedbread) -> None:
)
@parametrize
- def test_method_update(self, client: Mixedbread) -> None:
+ def test_method_update_overload_1(self, client: Mixedbread) -> None:
data_source = client.data_sources.update(
data_source_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ name="name",
)
assert_matches_type(DataSource, data_source, path=["response"])
@parametrize
- def test_method_update_with_all_params(self, client: Mixedbread) -> None:
+ def test_method_update_with_all_params_overload_1(self, client: Mixedbread) -> None:
data_source = client.data_sources.update(
data_source_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ type="notion",
name="name",
metadata={},
- auth_params={
- "type": "oauth2",
- "created_at": parse_datetime("2019-12-27T18:11:19.117Z"),
- "client_id": "client_id",
- "client_secret": "client_secret",
- "redirect_uri": "redirect_uri",
- "scope": "scope",
- "access_token": "access_token",
- "refresh_token": "refresh_token",
- "token_type": "token_type",
- "expires_on": parse_datetime("2019-12-27T18:11:19.117Z"),
- },
+ auth_params={"type": "oauth2"},
)
assert_matches_type(DataSource, data_source, path=["response"])
@parametrize
- def test_raw_response_update(self, client: Mixedbread) -> None:
+ def test_raw_response_update_overload_1(self, client: Mixedbread) -> None:
response = client.data_sources.with_raw_response.update(
data_source_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ name="name",
)
assert response.is_closed is True
@@ -155,9 +173,63 @@ def test_raw_response_update(self, client: Mixedbread) -> None:
assert_matches_type(DataSource, data_source, path=["response"])
@parametrize
- def test_streaming_response_update(self, client: Mixedbread) -> None:
+ def test_streaming_response_update_overload_1(self, client: Mixedbread) -> None:
with client.data_sources.with_streaming_response.update(
data_source_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ name="name",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ data_source = response.parse()
+ assert_matches_type(DataSource, data_source, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_update_overload_1(self, client: Mixedbread) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `data_source_id` but received ''"):
+ client.data_sources.with_raw_response.update(
+ data_source_id="",
+ name="name",
+ )
+
+ @parametrize
+ def test_method_update_overload_2(self, client: Mixedbread) -> None:
+ data_source = client.data_sources.update(
+ data_source_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ name="name",
+ )
+ assert_matches_type(DataSource, data_source, path=["response"])
+
+ @parametrize
+ def test_method_update_with_all_params_overload_2(self, client: Mixedbread) -> None:
+ data_source = client.data_sources.update(
+ data_source_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ type="notion",
+ name="name",
+ metadata={},
+ auth_params={"type": "oauth2"},
+ )
+ assert_matches_type(DataSource, data_source, path=["response"])
+
+ @parametrize
+ def test_raw_response_update_overload_2(self, client: Mixedbread) -> None:
+ response = client.data_sources.with_raw_response.update(
+ data_source_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ name="name",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ data_source = response.parse()
+ assert_matches_type(DataSource, data_source, path=["response"])
+
+ @parametrize
+ def test_streaming_response_update_overload_2(self, client: Mixedbread) -> None:
+ with client.data_sources.with_streaming_response.update(
+ data_source_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ name="name",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -168,10 +240,11 @@ def test_streaming_response_update(self, client: Mixedbread) -> None:
assert cast(Any, response.is_closed) is True
@parametrize
- def test_path_params_update(self, client: Mixedbread) -> None:
+ def test_path_params_update_overload_2(self, client: Mixedbread) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `data_source_id` but received ''"):
client.data_sources.with_raw_response.update(
data_source_id="",
+ name="name",
)
@parametrize
@@ -250,38 +323,25 @@ class TestAsyncDataSources:
parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
@parametrize
- async def test_method_create(self, async_client: AsyncMixedbread) -> None:
+ async def test_method_create_overload_1(self, async_client: AsyncMixedbread) -> None:
data_source = await async_client.data_sources.create(
- type="notion",
name="name",
)
assert_matches_type(DataSource, data_source, path=["response"])
@parametrize
- async def test_method_create_with_all_params(self, async_client: AsyncMixedbread) -> None:
+ async def test_method_create_with_all_params_overload_1(self, async_client: AsyncMixedbread) -> None:
data_source = await async_client.data_sources.create(
type="notion",
name="name",
metadata={},
- auth_params={
- "type": "oauth2",
- "created_at": parse_datetime("2019-12-27T18:11:19.117Z"),
- "client_id": "client_id",
- "client_secret": "client_secret",
- "redirect_uri": "redirect_uri",
- "scope": "scope",
- "access_token": "access_token",
- "refresh_token": "refresh_token",
- "token_type": "token_type",
- "expires_on": parse_datetime("2019-12-27T18:11:19.117Z"),
- },
+ auth_params={"type": "oauth2"},
)
assert_matches_type(DataSource, data_source, path=["response"])
@parametrize
- async def test_raw_response_create(self, async_client: AsyncMixedbread) -> None:
+ async def test_raw_response_create_overload_1(self, async_client: AsyncMixedbread) -> None:
response = await async_client.data_sources.with_raw_response.create(
- type="notion",
name="name",
)
@@ -291,10 +351,50 @@ async def test_raw_response_create(self, async_client: AsyncMixedbread) -> None:
assert_matches_type(DataSource, data_source, path=["response"])
@parametrize
- async def test_streaming_response_create(self, async_client: AsyncMixedbread) -> None:
+ async def test_streaming_response_create_overload_1(self, async_client: AsyncMixedbread) -> None:
async with async_client.data_sources.with_streaming_response.create(
+ name="name",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ data_source = await response.parse()
+ assert_matches_type(DataSource, data_source, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_create_overload_2(self, async_client: AsyncMixedbread) -> None:
+ data_source = await async_client.data_sources.create(
+ name="name",
+ )
+ assert_matches_type(DataSource, data_source, path=["response"])
+
+ @parametrize
+ async def test_method_create_with_all_params_overload_2(self, async_client: AsyncMixedbread) -> None:
+ data_source = await async_client.data_sources.create(
type="notion",
name="name",
+ metadata={},
+ auth_params={"type": "oauth2"},
+ )
+ assert_matches_type(DataSource, data_source, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create_overload_2(self, async_client: AsyncMixedbread) -> None:
+ response = await async_client.data_sources.with_raw_response.create(
+ name="name",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ data_source = await response.parse()
+ assert_matches_type(DataSource, data_source, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create_overload_2(self, async_client: AsyncMixedbread) -> None:
+ async with async_client.data_sources.with_streaming_response.create(
+ name="name",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -343,37 +443,29 @@ async def test_path_params_retrieve(self, async_client: AsyncMixedbread) -> None
)
@parametrize
- async def test_method_update(self, async_client: AsyncMixedbread) -> None:
+ async def test_method_update_overload_1(self, async_client: AsyncMixedbread) -> None:
data_source = await async_client.data_sources.update(
data_source_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ name="name",
)
assert_matches_type(DataSource, data_source, path=["response"])
@parametrize
- async def test_method_update_with_all_params(self, async_client: AsyncMixedbread) -> None:
+ async def test_method_update_with_all_params_overload_1(self, async_client: AsyncMixedbread) -> None:
data_source = await async_client.data_sources.update(
data_source_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ type="notion",
name="name",
metadata={},
- auth_params={
- "type": "oauth2",
- "created_at": parse_datetime("2019-12-27T18:11:19.117Z"),
- "client_id": "client_id",
- "client_secret": "client_secret",
- "redirect_uri": "redirect_uri",
- "scope": "scope",
- "access_token": "access_token",
- "refresh_token": "refresh_token",
- "token_type": "token_type",
- "expires_on": parse_datetime("2019-12-27T18:11:19.117Z"),
- },
+ auth_params={"type": "oauth2"},
)
assert_matches_type(DataSource, data_source, path=["response"])
@parametrize
- async def test_raw_response_update(self, async_client: AsyncMixedbread) -> None:
+ async def test_raw_response_update_overload_1(self, async_client: AsyncMixedbread) -> None:
response = await async_client.data_sources.with_raw_response.update(
data_source_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ name="name",
)
assert response.is_closed is True
@@ -382,9 +474,63 @@ async def test_raw_response_update(self, async_client: AsyncMixedbread) -> None:
assert_matches_type(DataSource, data_source, path=["response"])
@parametrize
- async def test_streaming_response_update(self, async_client: AsyncMixedbread) -> None:
+ async def test_streaming_response_update_overload_1(self, async_client: AsyncMixedbread) -> None:
async with async_client.data_sources.with_streaming_response.update(
data_source_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ name="name",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ data_source = await response.parse()
+ assert_matches_type(DataSource, data_source, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_update_overload_1(self, async_client: AsyncMixedbread) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `data_source_id` but received ''"):
+ await async_client.data_sources.with_raw_response.update(
+ data_source_id="",
+ name="name",
+ )
+
+ @parametrize
+ async def test_method_update_overload_2(self, async_client: AsyncMixedbread) -> None:
+ data_source = await async_client.data_sources.update(
+ data_source_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ name="name",
+ )
+ assert_matches_type(DataSource, data_source, path=["response"])
+
+ @parametrize
+ async def test_method_update_with_all_params_overload_2(self, async_client: AsyncMixedbread) -> None:
+ data_source = await async_client.data_sources.update(
+ data_source_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ type="notion",
+ name="name",
+ metadata={},
+ auth_params={"type": "oauth2"},
+ )
+ assert_matches_type(DataSource, data_source, path=["response"])
+
+ @parametrize
+ async def test_raw_response_update_overload_2(self, async_client: AsyncMixedbread) -> None:
+ response = await async_client.data_sources.with_raw_response.update(
+ data_source_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ name="name",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ data_source = await response.parse()
+ assert_matches_type(DataSource, data_source, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_update_overload_2(self, async_client: AsyncMixedbread) -> None:
+ async with async_client.data_sources.with_streaming_response.update(
+ data_source_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ name="name",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -395,10 +541,11 @@ async def test_streaming_response_update(self, async_client: AsyncMixedbread) ->
assert cast(Any, response.is_closed) is True
@parametrize
- async def test_path_params_update(self, async_client: AsyncMixedbread) -> None:
+ async def test_path_params_update_overload_2(self, async_client: AsyncMixedbread) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `data_source_id` but received ''"):
await async_client.data_sources.with_raw_response.update(
data_source_id="",
+ name="name",
)
@parametrize
diff --git a/tests/api_resources/test_vector_stores.py b/tests/api_resources/test_vector_stores.py
index 4cbe5b96..0dfbf64a 100644
--- a/tests/api_resources/test_vector_stores.py
+++ b/tests/api_resources/test_vector_stores.py
@@ -65,14 +65,14 @@ def test_streaming_response_create(self, client: Mixedbread) -> None:
@parametrize
def test_method_retrieve(self, client: Mixedbread) -> None:
vector_store = client.vector_stores.retrieve(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "vector_store_identifier",
)
assert_matches_type(VectorStore, vector_store, path=["response"])
@parametrize
def test_raw_response_retrieve(self, client: Mixedbread) -> None:
response = client.vector_stores.with_raw_response.retrieve(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "vector_store_identifier",
)
assert response.is_closed is True
@@ -83,7 +83,7 @@ def test_raw_response_retrieve(self, client: Mixedbread) -> None:
@parametrize
def test_streaming_response_retrieve(self, client: Mixedbread) -> None:
with client.vector_stores.with_streaming_response.retrieve(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "vector_store_identifier",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -95,7 +95,9 @@ def test_streaming_response_retrieve(self, client: Mixedbread) -> None:
@parametrize
def test_path_params_retrieve(self, client: Mixedbread) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `vector_store_id` but received ''"):
+ with pytest.raises(
+ ValueError, match=r"Expected a non-empty value for `vector_store_identifier` but received ''"
+ ):
client.vector_stores.with_raw_response.retrieve(
"",
)
@@ -103,14 +105,14 @@ def test_path_params_retrieve(self, client: Mixedbread) -> None:
@parametrize
def test_method_update(self, client: Mixedbread) -> None:
vector_store = client.vector_stores.update(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
)
assert_matches_type(VectorStore, vector_store, path=["response"])
@parametrize
def test_method_update_with_all_params(self, client: Mixedbread) -> None:
vector_store = client.vector_stores.update(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
name="x",
description="description",
expires_after={
@@ -124,7 +126,7 @@ def test_method_update_with_all_params(self, client: Mixedbread) -> None:
@parametrize
def test_raw_response_update(self, client: Mixedbread) -> None:
response = client.vector_stores.with_raw_response.update(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
)
assert response.is_closed is True
@@ -135,7 +137,7 @@ def test_raw_response_update(self, client: Mixedbread) -> None:
@parametrize
def test_streaming_response_update(self, client: Mixedbread) -> None:
with client.vector_stores.with_streaming_response.update(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -147,9 +149,11 @@ def test_streaming_response_update(self, client: Mixedbread) -> None:
@parametrize
def test_path_params_update(self, client: Mixedbread) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `vector_store_id` but received ''"):
+ with pytest.raises(
+ ValueError, match=r"Expected a non-empty value for `vector_store_identifier` but received ''"
+ ):
client.vector_stores.with_raw_response.update(
- vector_store_id="",
+ vector_store_identifier="",
)
@parametrize
@@ -162,6 +166,7 @@ def test_method_list_with_all_params(self, client: Mixedbread) -> None:
vector_store = client.vector_stores.list(
limit=1000,
offset=0,
+ q="x",
)
assert_matches_type(SyncLimitOffset[VectorStore], vector_store, path=["response"])
@@ -188,14 +193,14 @@ def test_streaming_response_list(self, client: Mixedbread) -> None:
@parametrize
def test_method_delete(self, client: Mixedbread) -> None:
vector_store = client.vector_stores.delete(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "vector_store_identifier",
)
assert_matches_type(VectorStoreDeleteResponse, vector_store, path=["response"])
@parametrize
def test_raw_response_delete(self, client: Mixedbread) -> None:
response = client.vector_stores.with_raw_response.delete(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "vector_store_identifier",
)
assert response.is_closed is True
@@ -206,7 +211,7 @@ def test_raw_response_delete(self, client: Mixedbread) -> None:
@parametrize
def test_streaming_response_delete(self, client: Mixedbread) -> None:
with client.vector_stores.with_streaming_response.delete(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "vector_store_identifier",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -218,23 +223,24 @@ def test_streaming_response_delete(self, client: Mixedbread) -> None:
@parametrize
def test_path_params_delete(self, client: Mixedbread) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `vector_store_id` but received ''"):
+ with pytest.raises(
+ ValueError, match=r"Expected a non-empty value for `vector_store_identifier` but received ''"
+ ):
client.vector_stores.with_raw_response.delete(
"",
)
@parametrize
def test_method_question_answering(self, client: Mixedbread) -> None:
- vector_store = client.vector_stores.question_answering(
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
- )
+ vector_store = client.vector_stores.question_answering()
assert_matches_type(VectorStoreQuestionAnsweringResponse, vector_store, path=["response"])
@parametrize
def test_method_question_answering_with_all_params(self, client: Mixedbread) -> None:
vector_store = client.vector_stores.question_answering(
query="x",
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
+ vector_store_identifiers=["string"],
+ vector_store_ids=["string"],
top_k=1,
filters={
"all": [
@@ -274,9 +280,11 @@ def test_method_question_answering_with_all_params(self, client: Mixedbread) ->
},
],
},
+ file_ids=["123e4567-e89b-12d3-a456-426614174000", "123e4567-e89b-12d3-a456-426614174001"],
search_options={
"score_threshold": 0,
"rewrite_query": True,
+ "rerank": True,
"return_metadata": True,
},
stream=True,
@@ -289,9 +297,7 @@ def test_method_question_answering_with_all_params(self, client: Mixedbread) ->
@parametrize
def test_raw_response_question_answering(self, client: Mixedbread) -> None:
- response = client.vector_stores.with_raw_response.question_answering(
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
- )
+ response = client.vector_stores.with_raw_response.question_answering()
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -300,9 +306,7 @@ def test_raw_response_question_answering(self, client: Mixedbread) -> None:
@parametrize
def test_streaming_response_question_answering(self, client: Mixedbread) -> None:
- with client.vector_stores.with_streaming_response.question_answering(
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
- ) as response:
+ with client.vector_stores.with_streaming_response.question_answering() as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -315,7 +319,6 @@ def test_streaming_response_question_answering(self, client: Mixedbread) -> None
def test_method_search(self, client: Mixedbread) -> None:
vector_store = client.vector_stores.search(
query="how to configure SSL",
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
)
assert_matches_type(VectorStoreSearchResponse, vector_store, path=["response"])
@@ -323,7 +326,8 @@ def test_method_search(self, client: Mixedbread) -> None:
def test_method_search_with_all_params(self, client: Mixedbread) -> None:
vector_store = client.vector_stores.search(
query="how to configure SSL",
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
+ vector_store_identifiers=["string"],
+ vector_store_ids=["string"],
top_k=1,
filters={
"all": [
@@ -363,9 +367,11 @@ def test_method_search_with_all_params(self, client: Mixedbread) -> None:
},
],
},
+ file_ids=["123e4567-e89b-12d3-a456-426614174000", "123e4567-e89b-12d3-a456-426614174001"],
search_options={
"score_threshold": 0,
"rewrite_query": True,
+ "rerank": True,
"return_metadata": True,
},
)
@@ -375,7 +381,6 @@ def test_method_search_with_all_params(self, client: Mixedbread) -> None:
def test_raw_response_search(self, client: Mixedbread) -> None:
response = client.vector_stores.with_raw_response.search(
query="how to configure SSL",
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
)
assert response.is_closed is True
@@ -387,7 +392,6 @@ def test_raw_response_search(self, client: Mixedbread) -> None:
def test_streaming_response_search(self, client: Mixedbread) -> None:
with client.vector_stores.with_streaming_response.search(
query="how to configure SSL",
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -443,14 +447,14 @@ async def test_streaming_response_create(self, async_client: AsyncMixedbread) ->
@parametrize
async def test_method_retrieve(self, async_client: AsyncMixedbread) -> None:
vector_store = await async_client.vector_stores.retrieve(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "vector_store_identifier",
)
assert_matches_type(VectorStore, vector_store, path=["response"])
@parametrize
async def test_raw_response_retrieve(self, async_client: AsyncMixedbread) -> None:
response = await async_client.vector_stores.with_raw_response.retrieve(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "vector_store_identifier",
)
assert response.is_closed is True
@@ -461,7 +465,7 @@ async def test_raw_response_retrieve(self, async_client: AsyncMixedbread) -> Non
@parametrize
async def test_streaming_response_retrieve(self, async_client: AsyncMixedbread) -> None:
async with async_client.vector_stores.with_streaming_response.retrieve(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "vector_store_identifier",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -473,7 +477,9 @@ async def test_streaming_response_retrieve(self, async_client: AsyncMixedbread)
@parametrize
async def test_path_params_retrieve(self, async_client: AsyncMixedbread) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `vector_store_id` but received ''"):
+ with pytest.raises(
+ ValueError, match=r"Expected a non-empty value for `vector_store_identifier` but received ''"
+ ):
await async_client.vector_stores.with_raw_response.retrieve(
"",
)
@@ -481,14 +487,14 @@ async def test_path_params_retrieve(self, async_client: AsyncMixedbread) -> None
@parametrize
async def test_method_update(self, async_client: AsyncMixedbread) -> None:
vector_store = await async_client.vector_stores.update(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
)
assert_matches_type(VectorStore, vector_store, path=["response"])
@parametrize
async def test_method_update_with_all_params(self, async_client: AsyncMixedbread) -> None:
vector_store = await async_client.vector_stores.update(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
name="x",
description="description",
expires_after={
@@ -502,7 +508,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncMixedbread
@parametrize
async def test_raw_response_update(self, async_client: AsyncMixedbread) -> None:
response = await async_client.vector_stores.with_raw_response.update(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
)
assert response.is_closed is True
@@ -513,7 +519,7 @@ async def test_raw_response_update(self, async_client: AsyncMixedbread) -> None:
@parametrize
async def test_streaming_response_update(self, async_client: AsyncMixedbread) -> None:
async with async_client.vector_stores.with_streaming_response.update(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -525,9 +531,11 @@ async def test_streaming_response_update(self, async_client: AsyncMixedbread) ->
@parametrize
async def test_path_params_update(self, async_client: AsyncMixedbread) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `vector_store_id` but received ''"):
+ with pytest.raises(
+ ValueError, match=r"Expected a non-empty value for `vector_store_identifier` but received ''"
+ ):
await async_client.vector_stores.with_raw_response.update(
- vector_store_id="",
+ vector_store_identifier="",
)
@parametrize
@@ -540,6 +548,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncMixedbread)
vector_store = await async_client.vector_stores.list(
limit=1000,
offset=0,
+ q="x",
)
assert_matches_type(AsyncLimitOffset[VectorStore], vector_store, path=["response"])
@@ -566,14 +575,14 @@ async def test_streaming_response_list(self, async_client: AsyncMixedbread) -> N
@parametrize
async def test_method_delete(self, async_client: AsyncMixedbread) -> None:
vector_store = await async_client.vector_stores.delete(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "vector_store_identifier",
)
assert_matches_type(VectorStoreDeleteResponse, vector_store, path=["response"])
@parametrize
async def test_raw_response_delete(self, async_client: AsyncMixedbread) -> None:
response = await async_client.vector_stores.with_raw_response.delete(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "vector_store_identifier",
)
assert response.is_closed is True
@@ -584,7 +593,7 @@ async def test_raw_response_delete(self, async_client: AsyncMixedbread) -> None:
@parametrize
async def test_streaming_response_delete(self, async_client: AsyncMixedbread) -> None:
async with async_client.vector_stores.with_streaming_response.delete(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "vector_store_identifier",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -596,23 +605,24 @@ async def test_streaming_response_delete(self, async_client: AsyncMixedbread) ->
@parametrize
async def test_path_params_delete(self, async_client: AsyncMixedbread) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `vector_store_id` but received ''"):
+ with pytest.raises(
+ ValueError, match=r"Expected a non-empty value for `vector_store_identifier` but received ''"
+ ):
await async_client.vector_stores.with_raw_response.delete(
"",
)
@parametrize
async def test_method_question_answering(self, async_client: AsyncMixedbread) -> None:
- vector_store = await async_client.vector_stores.question_answering(
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
- )
+ vector_store = await async_client.vector_stores.question_answering()
assert_matches_type(VectorStoreQuestionAnsweringResponse, vector_store, path=["response"])
@parametrize
async def test_method_question_answering_with_all_params(self, async_client: AsyncMixedbread) -> None:
vector_store = await async_client.vector_stores.question_answering(
query="x",
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
+ vector_store_identifiers=["string"],
+ vector_store_ids=["string"],
top_k=1,
filters={
"all": [
@@ -652,9 +662,11 @@ async def test_method_question_answering_with_all_params(self, async_client: Asy
},
],
},
+ file_ids=["123e4567-e89b-12d3-a456-426614174000", "123e4567-e89b-12d3-a456-426614174001"],
search_options={
"score_threshold": 0,
"rewrite_query": True,
+ "rerank": True,
"return_metadata": True,
},
stream=True,
@@ -667,9 +679,7 @@ async def test_method_question_answering_with_all_params(self, async_client: Asy
@parametrize
async def test_raw_response_question_answering(self, async_client: AsyncMixedbread) -> None:
- response = await async_client.vector_stores.with_raw_response.question_answering(
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
- )
+ response = await async_client.vector_stores.with_raw_response.question_answering()
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -678,9 +688,7 @@ async def test_raw_response_question_answering(self, async_client: AsyncMixedbre
@parametrize
async def test_streaming_response_question_answering(self, async_client: AsyncMixedbread) -> None:
- async with async_client.vector_stores.with_streaming_response.question_answering(
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
- ) as response:
+ async with async_client.vector_stores.with_streaming_response.question_answering() as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -693,7 +701,6 @@ async def test_streaming_response_question_answering(self, async_client: AsyncMi
async def test_method_search(self, async_client: AsyncMixedbread) -> None:
vector_store = await async_client.vector_stores.search(
query="how to configure SSL",
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
)
assert_matches_type(VectorStoreSearchResponse, vector_store, path=["response"])
@@ -701,7 +708,8 @@ async def test_method_search(self, async_client: AsyncMixedbread) -> None:
async def test_method_search_with_all_params(self, async_client: AsyncMixedbread) -> None:
vector_store = await async_client.vector_stores.search(
query="how to configure SSL",
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
+ vector_store_identifiers=["string"],
+ vector_store_ids=["string"],
top_k=1,
filters={
"all": [
@@ -741,9 +749,11 @@ async def test_method_search_with_all_params(self, async_client: AsyncMixedbread
},
],
},
+ file_ids=["123e4567-e89b-12d3-a456-426614174000", "123e4567-e89b-12d3-a456-426614174001"],
search_options={
"score_threshold": 0,
"rewrite_query": True,
+ "rerank": True,
"return_metadata": True,
},
)
@@ -753,7 +763,6 @@ async def test_method_search_with_all_params(self, async_client: AsyncMixedbread
async def test_raw_response_search(self, async_client: AsyncMixedbread) -> None:
response = await async_client.vector_stores.with_raw_response.search(
query="how to configure SSL",
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
)
assert response.is_closed is True
@@ -765,7 +774,6 @@ async def test_raw_response_search(self, async_client: AsyncMixedbread) -> None:
async def test_streaming_response_search(self, async_client: AsyncMixedbread) -> None:
async with async_client.vector_stores.with_streaming_response.search(
query="how to configure SSL",
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
diff --git a/tests/api_resources/vector_stores/test_files.py b/tests/api_resources/vector_stores/test_files.py
index e089a591..6a4128de 100644
--- a/tests/api_resources/vector_stores/test_files.py
+++ b/tests/api_resources/vector_stores/test_files.py
@@ -25,7 +25,7 @@ class TestFiles:
@parametrize
def test_method_create(self, client: Mixedbread) -> None:
file = client.vector_stores.files.create(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert_matches_type(VectorStoreFile, file, path=["response"])
@@ -33,7 +33,7 @@ def test_method_create(self, client: Mixedbread) -> None:
@parametrize
def test_method_create_with_all_params(self, client: Mixedbread) -> None:
file = client.vector_stores.files.create(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
metadata={},
experimental={
@@ -46,7 +46,7 @@ def test_method_create_with_all_params(self, client: Mixedbread) -> None:
@parametrize
def test_raw_response_create(self, client: Mixedbread) -> None:
response = client.vector_stores.files.with_raw_response.create(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
@@ -58,7 +58,7 @@ def test_raw_response_create(self, client: Mixedbread) -> None:
@parametrize
def test_streaming_response_create(self, client: Mixedbread) -> None:
with client.vector_stores.files.with_streaming_response.create(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
@@ -71,9 +71,11 @@ def test_streaming_response_create(self, client: Mixedbread) -> None:
@parametrize
def test_path_params_create(self, client: Mixedbread) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `vector_store_id` but received ''"):
+ with pytest.raises(
+ ValueError, match=r"Expected a non-empty value for `vector_store_identifier` but received ''"
+ ):
client.vector_stores.files.with_raw_response.create(
- vector_store_id="",
+ vector_store_identifier="",
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
@@ -81,7 +83,7 @@ def test_path_params_create(self, client: Mixedbread) -> None:
def test_method_retrieve(self, client: Mixedbread) -> None:
file = client.vector_stores.files.retrieve(
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
)
assert_matches_type(VectorStoreFile, file, path=["response"])
@@ -89,7 +91,7 @@ def test_method_retrieve(self, client: Mixedbread) -> None:
def test_raw_response_retrieve(self, client: Mixedbread) -> None:
response = client.vector_stores.files.with_raw_response.retrieve(
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
)
assert response.is_closed is True
@@ -101,7 +103,7 @@ def test_raw_response_retrieve(self, client: Mixedbread) -> None:
def test_streaming_response_retrieve(self, client: Mixedbread) -> None:
with client.vector_stores.files.with_streaming_response.retrieve(
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -113,29 +115,31 @@ def test_streaming_response_retrieve(self, client: Mixedbread) -> None:
@parametrize
def test_path_params_retrieve(self, client: Mixedbread) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `vector_store_id` but received ''"):
+ with pytest.raises(
+ ValueError, match=r"Expected a non-empty value for `vector_store_identifier` but received ''"
+ ):
client.vector_stores.files.with_raw_response.retrieve(
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- vector_store_id="",
+ vector_store_identifier="",
)
with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_id` but received ''"):
client.vector_stores.files.with_raw_response.retrieve(
file_id="",
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
)
@parametrize
def test_method_list(self, client: Mixedbread) -> None:
file = client.vector_stores.files.list(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
)
assert_matches_type(SyncLimitOffset[VectorStoreFile], file, path=["response"])
@parametrize
def test_method_list_with_all_params(self, client: Mixedbread) -> None:
file = client.vector_stores.files.list(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
limit=1000,
offset=0,
)
@@ -144,7 +148,7 @@ def test_method_list_with_all_params(self, client: Mixedbread) -> None:
@parametrize
def test_raw_response_list(self, client: Mixedbread) -> None:
response = client.vector_stores.files.with_raw_response.list(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
)
assert response.is_closed is True
@@ -155,7 +159,7 @@ def test_raw_response_list(self, client: Mixedbread) -> None:
@parametrize
def test_streaming_response_list(self, client: Mixedbread) -> None:
with client.vector_stores.files.with_streaming_response.list(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -167,16 +171,18 @@ def test_streaming_response_list(self, client: Mixedbread) -> None:
@parametrize
def test_path_params_list(self, client: Mixedbread) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `vector_store_id` but received ''"):
+ with pytest.raises(
+ ValueError, match=r"Expected a non-empty value for `vector_store_identifier` but received ''"
+ ):
client.vector_stores.files.with_raw_response.list(
- vector_store_id="",
+ vector_store_identifier="",
)
@parametrize
def test_method_delete(self, client: Mixedbread) -> None:
file = client.vector_stores.files.delete(
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
)
assert_matches_type(FileDeleteResponse, file, path=["response"])
@@ -184,7 +190,7 @@ def test_method_delete(self, client: Mixedbread) -> None:
def test_raw_response_delete(self, client: Mixedbread) -> None:
response = client.vector_stores.files.with_raw_response.delete(
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
)
assert response.is_closed is True
@@ -196,7 +202,7 @@ def test_raw_response_delete(self, client: Mixedbread) -> None:
def test_streaming_response_delete(self, client: Mixedbread) -> None:
with client.vector_stores.files.with_streaming_response.delete(
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -208,23 +214,24 @@ def test_streaming_response_delete(self, client: Mixedbread) -> None:
@parametrize
def test_path_params_delete(self, client: Mixedbread) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `vector_store_id` but received ''"):
+ with pytest.raises(
+ ValueError, match=r"Expected a non-empty value for `vector_store_identifier` but received ''"
+ ):
client.vector_stores.files.with_raw_response.delete(
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- vector_store_id="",
+ vector_store_identifier="",
)
with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_id` but received ''"):
client.vector_stores.files.with_raw_response.delete(
file_id="",
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
)
@parametrize
def test_method_search(self, client: Mixedbread) -> None:
file = client.vector_stores.files.search(
query="how to configure SSL",
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
)
assert_matches_type(FileSearchResponse, file, path=["response"])
@@ -232,7 +239,8 @@ def test_method_search(self, client: Mixedbread) -> None:
def test_method_search_with_all_params(self, client: Mixedbread) -> None:
file = client.vector_stores.files.search(
query="how to configure SSL",
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
+ vector_store_identifiers=["string"],
+ vector_store_ids=["string"],
top_k=1,
filters={
"all": [
@@ -272,9 +280,11 @@ def test_method_search_with_all_params(self, client: Mixedbread) -> None:
},
],
},
+ file_ids=["123e4567-e89b-12d3-a456-426614174000", "123e4567-e89b-12d3-a456-426614174001"],
search_options={
"score_threshold": 0,
"rewrite_query": True,
+ "rerank": True,
"return_metadata": True,
"return_chunks": True,
"chunks_per_file": 0,
@@ -286,7 +296,6 @@ def test_method_search_with_all_params(self, client: Mixedbread) -> None:
def test_raw_response_search(self, client: Mixedbread) -> None:
response = client.vector_stores.files.with_raw_response.search(
query="how to configure SSL",
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
)
assert response.is_closed is True
@@ -298,7 +307,6 @@ def test_raw_response_search(self, client: Mixedbread) -> None:
def test_streaming_response_search(self, client: Mixedbread) -> None:
with client.vector_stores.files.with_streaming_response.search(
query="how to configure SSL",
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -315,7 +323,7 @@ class TestAsyncFiles:
@parametrize
async def test_method_create(self, async_client: AsyncMixedbread) -> None:
file = await async_client.vector_stores.files.create(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert_matches_type(VectorStoreFile, file, path=["response"])
@@ -323,7 +331,7 @@ async def test_method_create(self, async_client: AsyncMixedbread) -> None:
@parametrize
async def test_method_create_with_all_params(self, async_client: AsyncMixedbread) -> None:
file = await async_client.vector_stores.files.create(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
metadata={},
experimental={
@@ -336,7 +344,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncMixedbread
@parametrize
async def test_raw_response_create(self, async_client: AsyncMixedbread) -> None:
response = await async_client.vector_stores.files.with_raw_response.create(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
@@ -348,7 +356,7 @@ async def test_raw_response_create(self, async_client: AsyncMixedbread) -> None:
@parametrize
async def test_streaming_response_create(self, async_client: AsyncMixedbread) -> None:
async with async_client.vector_stores.files.with_streaming_response.create(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
@@ -361,9 +369,11 @@ async def test_streaming_response_create(self, async_client: AsyncMixedbread) ->
@parametrize
async def test_path_params_create(self, async_client: AsyncMixedbread) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `vector_store_id` but received ''"):
+ with pytest.raises(
+ ValueError, match=r"Expected a non-empty value for `vector_store_identifier` but received ''"
+ ):
await async_client.vector_stores.files.with_raw_response.create(
- vector_store_id="",
+ vector_store_identifier="",
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
@@ -371,7 +381,7 @@ async def test_path_params_create(self, async_client: AsyncMixedbread) -> None:
async def test_method_retrieve(self, async_client: AsyncMixedbread) -> None:
file = await async_client.vector_stores.files.retrieve(
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
)
assert_matches_type(VectorStoreFile, file, path=["response"])
@@ -379,7 +389,7 @@ async def test_method_retrieve(self, async_client: AsyncMixedbread) -> None:
async def test_raw_response_retrieve(self, async_client: AsyncMixedbread) -> None:
response = await async_client.vector_stores.files.with_raw_response.retrieve(
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
)
assert response.is_closed is True
@@ -391,7 +401,7 @@ async def test_raw_response_retrieve(self, async_client: AsyncMixedbread) -> Non
async def test_streaming_response_retrieve(self, async_client: AsyncMixedbread) -> None:
async with async_client.vector_stores.files.with_streaming_response.retrieve(
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -403,29 +413,31 @@ async def test_streaming_response_retrieve(self, async_client: AsyncMixedbread)
@parametrize
async def test_path_params_retrieve(self, async_client: AsyncMixedbread) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `vector_store_id` but received ''"):
+ with pytest.raises(
+ ValueError, match=r"Expected a non-empty value for `vector_store_identifier` but received ''"
+ ):
await async_client.vector_stores.files.with_raw_response.retrieve(
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- vector_store_id="",
+ vector_store_identifier="",
)
with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_id` but received ''"):
await async_client.vector_stores.files.with_raw_response.retrieve(
file_id="",
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
)
@parametrize
async def test_method_list(self, async_client: AsyncMixedbread) -> None:
file = await async_client.vector_stores.files.list(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
)
assert_matches_type(AsyncLimitOffset[VectorStoreFile], file, path=["response"])
@parametrize
async def test_method_list_with_all_params(self, async_client: AsyncMixedbread) -> None:
file = await async_client.vector_stores.files.list(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
limit=1000,
offset=0,
)
@@ -434,7 +446,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncMixedbread)
@parametrize
async def test_raw_response_list(self, async_client: AsyncMixedbread) -> None:
response = await async_client.vector_stores.files.with_raw_response.list(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
)
assert response.is_closed is True
@@ -445,7 +457,7 @@ async def test_raw_response_list(self, async_client: AsyncMixedbread) -> None:
@parametrize
async def test_streaming_response_list(self, async_client: AsyncMixedbread) -> None:
async with async_client.vector_stores.files.with_streaming_response.list(
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -457,16 +469,18 @@ async def test_streaming_response_list(self, async_client: AsyncMixedbread) -> N
@parametrize
async def test_path_params_list(self, async_client: AsyncMixedbread) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `vector_store_id` but received ''"):
+ with pytest.raises(
+ ValueError, match=r"Expected a non-empty value for `vector_store_identifier` but received ''"
+ ):
await async_client.vector_stores.files.with_raw_response.list(
- vector_store_id="",
+ vector_store_identifier="",
)
@parametrize
async def test_method_delete(self, async_client: AsyncMixedbread) -> None:
file = await async_client.vector_stores.files.delete(
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
)
assert_matches_type(FileDeleteResponse, file, path=["response"])
@@ -474,7 +488,7 @@ async def test_method_delete(self, async_client: AsyncMixedbread) -> None:
async def test_raw_response_delete(self, async_client: AsyncMixedbread) -> None:
response = await async_client.vector_stores.files.with_raw_response.delete(
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
)
assert response.is_closed is True
@@ -486,7 +500,7 @@ async def test_raw_response_delete(self, async_client: AsyncMixedbread) -> None:
async def test_streaming_response_delete(self, async_client: AsyncMixedbread) -> None:
async with async_client.vector_stores.files.with_streaming_response.delete(
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -498,23 +512,24 @@ async def test_streaming_response_delete(self, async_client: AsyncMixedbread) ->
@parametrize
async def test_path_params_delete(self, async_client: AsyncMixedbread) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `vector_store_id` but received ''"):
+ with pytest.raises(
+ ValueError, match=r"Expected a non-empty value for `vector_store_identifier` but received ''"
+ ):
await async_client.vector_stores.files.with_raw_response.delete(
file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- vector_store_id="",
+ vector_store_identifier="",
)
with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_id` but received ''"):
await async_client.vector_stores.files.with_raw_response.delete(
file_id="",
- vector_store_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ vector_store_identifier="vector_store_identifier",
)
@parametrize
async def test_method_search(self, async_client: AsyncMixedbread) -> None:
file = await async_client.vector_stores.files.search(
query="how to configure SSL",
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
)
assert_matches_type(FileSearchResponse, file, path=["response"])
@@ -522,7 +537,8 @@ async def test_method_search(self, async_client: AsyncMixedbread) -> None:
async def test_method_search_with_all_params(self, async_client: AsyncMixedbread) -> None:
file = await async_client.vector_stores.files.search(
query="how to configure SSL",
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
+ vector_store_identifiers=["string"],
+ vector_store_ids=["string"],
top_k=1,
filters={
"all": [
@@ -562,9 +578,11 @@ async def test_method_search_with_all_params(self, async_client: AsyncMixedbread
},
],
},
+ file_ids=["123e4567-e89b-12d3-a456-426614174000", "123e4567-e89b-12d3-a456-426614174001"],
search_options={
"score_threshold": 0,
"rewrite_query": True,
+ "rerank": True,
"return_metadata": True,
"return_chunks": True,
"chunks_per_file": 0,
@@ -576,7 +594,6 @@ async def test_method_search_with_all_params(self, async_client: AsyncMixedbread
async def test_raw_response_search(self, async_client: AsyncMixedbread) -> None:
response = await async_client.vector_stores.files.with_raw_response.search(
query="how to configure SSL",
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
)
assert response.is_closed is True
@@ -588,7 +605,6 @@ async def test_raw_response_search(self, async_client: AsyncMixedbread) -> None:
async def test_streaming_response_search(self, async_client: AsyncMixedbread) -> None:
async with async_client.vector_stores.files.with_streaming_response.search(
query="how to configure SSL",
- vector_store_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
diff --git a/tests/test_client.py b/tests/test_client.py
index 4d16384d..61377980 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -836,6 +836,33 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
assert response.http_request.headers.get("x-stainless-retry-count") == "42"
+ @pytest.mark.respx(base_url=base_url)
+ def test_follow_redirects(self, respx_mock: MockRouter) -> None:
+ # Test that the default follow_redirects=True allows following redirects
+ respx_mock.post("/redirect").mock(
+ return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"})
+ )
+ respx_mock.get("/redirected").mock(return_value=httpx.Response(200, json={"status": "ok"}))
+
+ response = self.client.post("/redirect", body={"key": "value"}, cast_to=httpx.Response)
+ assert response.status_code == 200
+ assert response.json() == {"status": "ok"}
+
+ @pytest.mark.respx(base_url=base_url)
+ def test_follow_redirects_disabled(self, respx_mock: MockRouter) -> None:
+ # Test that follow_redirects=False prevents following redirects
+ respx_mock.post("/redirect").mock(
+ return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"})
+ )
+
+ with pytest.raises(APIStatusError) as exc_info:
+ self.client.post(
+ "/redirect", body={"key": "value"}, options={"follow_redirects": False}, cast_to=httpx.Response
+ )
+
+ assert exc_info.value.response.status_code == 302
+ assert exc_info.value.response.headers["Location"] == f"{base_url}/redirected"
+
class TestAsyncMixedbread:
client = AsyncMixedbread(base_url=base_url, api_key=api_key, _strict_response_validation=True)
@@ -1671,3 +1698,30 @@ async def test_main() -> None:
raise AssertionError("calling get_platform using asyncify resulted in a hung process")
time.sleep(0.1)
+
+ @pytest.mark.respx(base_url=base_url)
+ async def test_follow_redirects(self, respx_mock: MockRouter) -> None:
+ # Test that the default follow_redirects=True allows following redirects
+ respx_mock.post("/redirect").mock(
+ return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"})
+ )
+ respx_mock.get("/redirected").mock(return_value=httpx.Response(200, json={"status": "ok"}))
+
+ response = await self.client.post("/redirect", body={"key": "value"}, cast_to=httpx.Response)
+ assert response.status_code == 200
+ assert response.json() == {"status": "ok"}
+
+ @pytest.mark.respx(base_url=base_url)
+ async def test_follow_redirects_disabled(self, respx_mock: MockRouter) -> None:
+ # Test that follow_redirects=False prevents following redirects
+ respx_mock.post("/redirect").mock(
+ return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"})
+ )
+
+ with pytest.raises(APIStatusError) as exc_info:
+ await self.client.post(
+ "/redirect", body={"key": "value"}, options={"follow_redirects": False}, cast_to=httpx.Response
+ )
+
+ assert exc_info.value.response.status_code == 302
+ assert exc_info.value.response.headers["Location"] == f"{base_url}/redirected"