diff --git a/.release-please-manifest.json b/.release-please-manifest.json index e4e1c3ce..ce5e5c7c 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.34.0" + ".": "0.35.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 5148ba96..d8c421cd 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 61 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/mixedbread%2Fmixedbread-a14d1b895964291692e90504f3db6d263a4a8d9cca6f1137548ceae0fdc5d82e.yml -openapi_spec_hash: 0608955c434731be0e392470f511e026 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/mixedbread%2Fmixedbread-d4c4a6e0d99b371dc5e84a63cf447770fc684d6a0650b2e36013404245a5876b.yml +openapi_spec_hash: 9d377ce6164438d3207d8a50c954a9cd config_hash: 2de40c343cf7b242d5925e3405ee8908 diff --git a/CHANGELOG.md b/CHANGELOG.md index 3daeb4b9..49bd5fbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog +## 0.35.0 (2025-10-30) + +Full Changelog: [v0.34.0...v0.35.0](https://github.com/mixedbread-ai/mixedbread-python/compare/v0.34.0...v0.35.0) + +### Features + +* **api:** api update ([26a066f](https://github.com/mixedbread-ai/mixedbread-python/commit/26a066f062d33164f0105c470c3fbfd3a1e0d3e1)) + + +### Bug Fixes + +* **client:** close streams without requiring full consumption ([c348610](https://github.com/mixedbread-ai/mixedbread-python/commit/c34861040d2cd5944b48f11703cd3c3f9da350a5)) + + +### Chores + +* bump `httpx-aiohttp` version to 0.1.9 ([305ea76](https://github.com/mixedbread-ai/mixedbread-python/commit/305ea7688a2e04ffef03dabd815e0a0c28613b5e)) +* **internal:** detect missing future annotations with ruff ([7683f5b](https://github.com/mixedbread-ai/mixedbread-python/commit/7683f5b7fc7aa498218782ef170645d2484f655c)) + ## 0.34.0 (2025-10-08) Full Changelog: [v0.33.0...v0.34.0](https://github.com/mixedbread-ai/mixedbread-python/compare/v0.33.0...v0.34.0) diff --git a/pyproject.toml b/pyproject.toml index f5c946c4..cc1d73b6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "mixedbread" -version = "0.34.0" +version = "0.35.0" description = "The official Python library for the Mixedbread API" dynamic = ["readme"] license = "Apache-2.0" @@ -39,7 +39,7 @@ Homepage = "https://github.com/mixedbread-ai/mixedbread-python" Repository = "https://github.com/mixedbread-ai/mixedbread-python" [project.optional-dependencies] -aiohttp = ["aiohttp", "httpx_aiohttp>=0.1.8"] +aiohttp = ["aiohttp", "httpx_aiohttp>=0.1.9"] [tool.rye] managed = true @@ -224,6 +224,8 @@ select = [ "B", # remove unused imports "F401", + # check for missing future annotations + "FA102", # bare except statements "E722", # unused arguments @@ -246,6 +248,8 @@ unfixable = [ "T203", ] +extend-safe-fixes = ["FA102"] + [tool.ruff.lint.flake8-tidy-imports.banned-api] "functools.lru_cache".msg = "This function does not retain type information for the wrapped function's arguments; The `lru_cache` function from `_utils` should be used instead" diff --git a/requirements-dev.lock b/requirements-dev.lock index f24d36ed..3813c2e4 100644 --- a/requirements-dev.lock +++ b/requirements-dev.lock @@ -56,7 +56,7 @@ httpx==0.28.1 # via httpx-aiohttp # via mixedbread # via respx -httpx-aiohttp==0.1.8 +httpx-aiohttp==0.1.9 # via mixedbread idna==3.4 # via anyio diff --git a/requirements.lock b/requirements.lock index 57e00706..8d80628d 100644 --- a/requirements.lock +++ b/requirements.lock @@ -43,7 +43,7 @@ httpcore==1.0.9 httpx==0.28.1 # via httpx-aiohttp # via mixedbread -httpx-aiohttp==0.1.8 +httpx-aiohttp==0.1.9 # via mixedbread idna==3.4 # via anyio diff --git a/src/mixedbread/_streaming.py b/src/mixedbread/_streaming.py index e5834ace..ffe39031 100644 --- a/src/mixedbread/_streaming.py +++ b/src/mixedbread/_streaming.py @@ -57,9 +57,8 @@ def __stream__(self) -> Iterator[_T]: for sse in iterator: yield process_data(data=sse.json(), cast_to=cast_to, response=response) - # Ensure the entire stream is consumed - for _sse in iterator: - ... + # As we might not fully consume the response stream, we need to close it explicitly + response.close() def __enter__(self) -> Self: return self @@ -121,9 +120,8 @@ async def __stream__(self) -> AsyncIterator[_T]: async for sse in iterator: yield process_data(data=sse.json(), cast_to=cast_to, response=response) - # Ensure the entire stream is consumed - async for _sse in iterator: - ... + # As we might not fully consume the response stream, we need to close it explicitly + await response.aclose() async def __aenter__(self) -> Self: return self diff --git a/src/mixedbread/_version.py b/src/mixedbread/_version.py index 9e8303ed..372ffb33 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.34.0" # x-release-please-version +__version__ = "0.35.0" # x-release-please-version diff --git a/src/mixedbread/resources/api_keys.py b/src/mixedbread/resources/api_keys.py index f304929e..66408456 100644 --- a/src/mixedbread/resources/api_keys.py +++ b/src/mixedbread/resources/api_keys.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Union +from typing import Union, Iterable, Optional from datetime import datetime import httpx @@ -51,6 +51,7 @@ def create( self, *, name: str | Omit = omit, + scope: Optional[Iterable[api_key_create_params.Scope]] | Omit = omit, expires_at: Union[str, datetime, None] | Omit = omit, # 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. @@ -70,6 +71,8 @@ def create( Args: name: A name/description for the API key + scope: The scope of the API key + expires_at: Optional expiration datetime extra_headers: Send extra headers @@ -85,6 +88,7 @@ def create( body=maybe_transform( { "name": name, + "scope": scope, "expires_at": expires_at, }, api_key_create_params.APIKeyCreateParams, @@ -331,6 +335,7 @@ async def create( self, *, name: str | Omit = omit, + scope: Optional[Iterable[api_key_create_params.Scope]] | Omit = omit, expires_at: Union[str, datetime, None] | Omit = omit, # 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. @@ -350,6 +355,8 @@ async def create( Args: name: A name/description for the API key + scope: The scope of the API key + expires_at: Optional expiration datetime extra_headers: Send extra headers @@ -365,6 +372,7 @@ async def create( body=await async_maybe_transform( { "name": name, + "scope": scope, "expires_at": expires_at, }, api_key_create_params.APIKeyCreateParams, diff --git a/src/mixedbread/types/api_key.py b/src/mixedbread/types/api_key.py index 15e7cbc2..87a23797 100644 --- a/src/mixedbread/types/api_key.py +++ b/src/mixedbread/types/api_key.py @@ -1,12 +1,20 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Optional from datetime import datetime from typing_extensions import Literal from .._models import BaseModel -__all__ = ["APIKey"] +__all__ = ["APIKey", "Scope"] + + +class Scope(BaseModel): + method: Literal["read", "write", "delete", "list", "create"] + + resource_type: Optional[Literal["store"]] = None + + resource_id: Optional[str] = None class APIKey(BaseModel): @@ -33,3 +41,6 @@ class APIKey(BaseModel): object: Optional[Literal["api_key"]] = None """The type of the object""" + + scope: Optional[List[Scope]] = None + """The scope of the API key""" diff --git a/src/mixedbread/types/api_key_create_params.py b/src/mixedbread/types/api_key_create_params.py index 074ae0e0..a7687543 100644 --- a/src/mixedbread/types/api_key_create_params.py +++ b/src/mixedbread/types/api_key_create_params.py @@ -2,18 +2,29 @@ from __future__ import annotations -from typing import Union +from typing import Union, Iterable, Optional from datetime import datetime -from typing_extensions import Annotated, TypedDict +from typing_extensions import Literal, Required, Annotated, TypedDict from .._utils import PropertyInfo -__all__ = ["APIKeyCreateParams"] +__all__ = ["APIKeyCreateParams", "Scope"] class APIKeyCreateParams(TypedDict, total=False): name: str """A name/description for the API key""" + scope: Optional[Iterable[Scope]] + """The scope of the API key""" + expires_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] """Optional expiration datetime""" + + +class Scope(TypedDict, total=False): + method: Required[Literal["read", "write", "delete", "list", "create"]] + + resource_type: Optional[Literal["store"]] + + resource_id: Optional[str] diff --git a/src/mixedbread/types/api_key_created.py b/src/mixedbread/types/api_key_created.py index 052910e8..08f16806 100644 --- a/src/mixedbread/types/api_key_created.py +++ b/src/mixedbread/types/api_key_created.py @@ -1,12 +1,20 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Optional from datetime import datetime from typing_extensions import Literal from .._models import BaseModel -__all__ = ["APIKeyCreated"] +__all__ = ["APIKeyCreated", "Scope"] + + +class Scope(BaseModel): + method: Literal["read", "write", "delete", "list", "create"] + + resource_type: Optional[Literal["store"]] = None + + resource_id: Optional[str] = None class APIKeyCreated(BaseModel): @@ -34,5 +42,8 @@ class APIKeyCreated(BaseModel): object: Optional[Literal["api_key"]] = None """The type of the object""" + scope: Optional[List[Scope]] = None + """The scope of the API key""" + value: str """The value of the API key""" diff --git a/tests/api_resources/test_api_keys.py b/tests/api_resources/test_api_keys.py index 7da5d8aa..aa8310ee 100644 --- a/tests/api_resources/test_api_keys.py +++ b/tests/api_resources/test_api_keys.py @@ -28,6 +28,13 @@ def test_method_create(self, client: Mixedbread) -> None: def test_method_create_with_all_params(self, client: Mixedbread) -> None: api_key = client.api_keys.create( name="name", + scope=[ + { + "method": "read", + "resource_type": "store", + "resource_id": "resource_id", + } + ], expires_at=parse_datetime("2019-12-27T18:11:19.117Z"), ) assert_matches_type(APIKeyCreated, api_key, path=["response"]) @@ -252,6 +259,13 @@ async def test_method_create(self, async_client: AsyncMixedbread) -> None: async def test_method_create_with_all_params(self, async_client: AsyncMixedbread) -> None: api_key = await async_client.api_keys.create( name="name", + scope=[ + { + "method": "read", + "resource_type": "store", + "resource_id": "resource_id", + } + ], expires_at=parse_datetime("2019-12-27T18:11:19.117Z"), ) assert_matches_type(APIKeyCreated, api_key, path=["response"])