From ba6fc65657b77abc6fc59aed3053e3d3d4c6ec84 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 16 Dec 2025 04:29:43 +0000 Subject: [PATCH 1/5] chore(internal): add missing files argument to base client --- src/blooio/_base_client.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/blooio/_base_client.py b/src/blooio/_base_client.py index 1ba2aac..f85e4f3 100644 --- a/src/blooio/_base_client.py +++ b/src/blooio/_base_client.py @@ -1247,9 +1247,12 @@ def patch( *, cast_to: Type[ResponseT], body: Body | None = None, + files: RequestFiles | None = None, options: RequestOptions = {}, ) -> ResponseT: - opts = FinalRequestOptions.construct(method="patch", url=path, json_data=body, **options) + opts = FinalRequestOptions.construct( + method="patch", url=path, json_data=body, files=to_httpx_files(files), **options + ) return self.request(cast_to, opts) def put( @@ -1767,9 +1770,12 @@ async def patch( *, cast_to: Type[ResponseT], body: Body | None = None, + files: RequestFiles | None = None, options: RequestOptions = {}, ) -> ResponseT: - opts = FinalRequestOptions.construct(method="patch", url=path, json_data=body, **options) + opts = FinalRequestOptions.construct( + method="patch", url=path, json_data=body, files=to_httpx_files(files), **options + ) return await self.request(cast_to, opts) async def put( From 512dd3980296e17dcc7e02f508a295ff5e498d8d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 06:04:29 +0000 Subject: [PATCH 2/5] chore: speedup initial import --- src/blooio/_client.py | 269 +++++++++++++++++++++++++++++++++--------- 1 file changed, 216 insertions(+), 53 deletions(-) diff --git a/src/blooio/_client.py b/src/blooio/_client.py index ec18936..540214b 100644 --- a/src/blooio/_client.py +++ b/src/blooio/_client.py @@ -3,7 +3,7 @@ from __future__ import annotations import os -from typing import Any, Mapping +from typing import TYPE_CHECKING, Any, Mapping from typing_extensions import Self, override import httpx @@ -20,8 +20,8 @@ not_given, ) from ._utils import is_given, get_async_library +from ._compat import cached_property from ._version import __version__ -from .resources import me, batches, contacts, messages from ._streaming import Stream as Stream, AsyncStream as AsyncStream from ._exceptions import BlooioError, APIStatusError from ._base_client import ( @@ -29,20 +29,19 @@ SyncAPIClient, AsyncAPIClient, ) -from .resources.config import config + +if TYPE_CHECKING: + from .resources import me, config, batches, contacts, messages + from .resources.me import MeResource, AsyncMeResource + from .resources.batches import BatchesResource, AsyncBatchesResource + from .resources.contacts import ContactsResource, AsyncContactsResource + from .resources.messages import MessagesResource, AsyncMessagesResource + from .resources.config.config import ConfigResource, AsyncConfigResource __all__ = ["Timeout", "Transport", "ProxiesTypes", "RequestOptions", "Blooio", "AsyncBlooio", "Client", "AsyncClient"] class Blooio(SyncAPIClient): - me: me.MeResource - contacts: contacts.ContactsResource - messages: messages.MessagesResource - config: config.ConfigResource - batches: batches.BatchesResource - with_raw_response: BlooioWithRawResponse - with_streaming_response: BlooioWithStreamedResponse - # client options api_key: str @@ -97,13 +96,43 @@ def __init__( _strict_response_validation=_strict_response_validation, ) - self.me = me.MeResource(self) - self.contacts = contacts.ContactsResource(self) - self.messages = messages.MessagesResource(self) - self.config = config.ConfigResource(self) - self.batches = batches.BatchesResource(self) - self.with_raw_response = BlooioWithRawResponse(self) - self.with_streaming_response = BlooioWithStreamedResponse(self) + @cached_property + def me(self) -> MeResource: + from .resources.me import MeResource + + return MeResource(self) + + @cached_property + def contacts(self) -> ContactsResource: + from .resources.contacts import ContactsResource + + return ContactsResource(self) + + @cached_property + def messages(self) -> MessagesResource: + from .resources.messages import MessagesResource + + return MessagesResource(self) + + @cached_property + def config(self) -> ConfigResource: + from .resources.config import ConfigResource + + return ConfigResource(self) + + @cached_property + def batches(self) -> BatchesResource: + from .resources.batches import BatchesResource + + return BatchesResource(self) + + @cached_property + def with_raw_response(self) -> BlooioWithRawResponse: + return BlooioWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> BlooioWithStreamedResponse: + return BlooioWithStreamedResponse(self) @property @override @@ -211,14 +240,6 @@ def _make_status_error( class AsyncBlooio(AsyncAPIClient): - me: me.AsyncMeResource - contacts: contacts.AsyncContactsResource - messages: messages.AsyncMessagesResource - config: config.AsyncConfigResource - batches: batches.AsyncBatchesResource - with_raw_response: AsyncBlooioWithRawResponse - with_streaming_response: AsyncBlooioWithStreamedResponse - # client options api_key: str @@ -273,13 +294,43 @@ def __init__( _strict_response_validation=_strict_response_validation, ) - self.me = me.AsyncMeResource(self) - self.contacts = contacts.AsyncContactsResource(self) - self.messages = messages.AsyncMessagesResource(self) - self.config = config.AsyncConfigResource(self) - self.batches = batches.AsyncBatchesResource(self) - self.with_raw_response = AsyncBlooioWithRawResponse(self) - self.with_streaming_response = AsyncBlooioWithStreamedResponse(self) + @cached_property + def me(self) -> AsyncMeResource: + from .resources.me import AsyncMeResource + + return AsyncMeResource(self) + + @cached_property + def contacts(self) -> AsyncContactsResource: + from .resources.contacts import AsyncContactsResource + + return AsyncContactsResource(self) + + @cached_property + def messages(self) -> AsyncMessagesResource: + from .resources.messages import AsyncMessagesResource + + return AsyncMessagesResource(self) + + @cached_property + def config(self) -> AsyncConfigResource: + from .resources.config import AsyncConfigResource + + return AsyncConfigResource(self) + + @cached_property + def batches(self) -> AsyncBatchesResource: + from .resources.batches import AsyncBatchesResource + + return AsyncBatchesResource(self) + + @cached_property + def with_raw_response(self) -> AsyncBlooioWithRawResponse: + return AsyncBlooioWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncBlooioWithStreamedResponse: + return AsyncBlooioWithStreamedResponse(self) @property @override @@ -387,39 +438,151 @@ def _make_status_error( class BlooioWithRawResponse: + _client: Blooio + def __init__(self, client: Blooio) -> None: - self.me = me.MeResourceWithRawResponse(client.me) - self.contacts = contacts.ContactsResourceWithRawResponse(client.contacts) - self.messages = messages.MessagesResourceWithRawResponse(client.messages) - self.config = config.ConfigResourceWithRawResponse(client.config) - self.batches = batches.BatchesResourceWithRawResponse(client.batches) + self._client = client + + @cached_property + def me(self) -> me.MeResourceWithRawResponse: + from .resources.me import MeResourceWithRawResponse + + return MeResourceWithRawResponse(self._client.me) + + @cached_property + def contacts(self) -> contacts.ContactsResourceWithRawResponse: + from .resources.contacts import ContactsResourceWithRawResponse + + return ContactsResourceWithRawResponse(self._client.contacts) + + @cached_property + def messages(self) -> messages.MessagesResourceWithRawResponse: + from .resources.messages import MessagesResourceWithRawResponse + + return MessagesResourceWithRawResponse(self._client.messages) + + @cached_property + def config(self) -> config.ConfigResourceWithRawResponse: + from .resources.config import ConfigResourceWithRawResponse + + return ConfigResourceWithRawResponse(self._client.config) + + @cached_property + def batches(self) -> batches.BatchesResourceWithRawResponse: + from .resources.batches import BatchesResourceWithRawResponse + + return BatchesResourceWithRawResponse(self._client.batches) class AsyncBlooioWithRawResponse: + _client: AsyncBlooio + def __init__(self, client: AsyncBlooio) -> None: - self.me = me.AsyncMeResourceWithRawResponse(client.me) - self.contacts = contacts.AsyncContactsResourceWithRawResponse(client.contacts) - self.messages = messages.AsyncMessagesResourceWithRawResponse(client.messages) - self.config = config.AsyncConfigResourceWithRawResponse(client.config) - self.batches = batches.AsyncBatchesResourceWithRawResponse(client.batches) + self._client = client + + @cached_property + def me(self) -> me.AsyncMeResourceWithRawResponse: + from .resources.me import AsyncMeResourceWithRawResponse + + return AsyncMeResourceWithRawResponse(self._client.me) + + @cached_property + def contacts(self) -> contacts.AsyncContactsResourceWithRawResponse: + from .resources.contacts import AsyncContactsResourceWithRawResponse + + return AsyncContactsResourceWithRawResponse(self._client.contacts) + + @cached_property + def messages(self) -> messages.AsyncMessagesResourceWithRawResponse: + from .resources.messages import AsyncMessagesResourceWithRawResponse + + return AsyncMessagesResourceWithRawResponse(self._client.messages) + + @cached_property + def config(self) -> config.AsyncConfigResourceWithRawResponse: + from .resources.config import AsyncConfigResourceWithRawResponse + + return AsyncConfigResourceWithRawResponse(self._client.config) + + @cached_property + def batches(self) -> batches.AsyncBatchesResourceWithRawResponse: + from .resources.batches import AsyncBatchesResourceWithRawResponse + + return AsyncBatchesResourceWithRawResponse(self._client.batches) class BlooioWithStreamedResponse: + _client: Blooio + def __init__(self, client: Blooio) -> None: - self.me = me.MeResourceWithStreamingResponse(client.me) - self.contacts = contacts.ContactsResourceWithStreamingResponse(client.contacts) - self.messages = messages.MessagesResourceWithStreamingResponse(client.messages) - self.config = config.ConfigResourceWithStreamingResponse(client.config) - self.batches = batches.BatchesResourceWithStreamingResponse(client.batches) + self._client = client + + @cached_property + def me(self) -> me.MeResourceWithStreamingResponse: + from .resources.me import MeResourceWithStreamingResponse + + return MeResourceWithStreamingResponse(self._client.me) + + @cached_property + def contacts(self) -> contacts.ContactsResourceWithStreamingResponse: + from .resources.contacts import ContactsResourceWithStreamingResponse + + return ContactsResourceWithStreamingResponse(self._client.contacts) + + @cached_property + def messages(self) -> messages.MessagesResourceWithStreamingResponse: + from .resources.messages import MessagesResourceWithStreamingResponse + + return MessagesResourceWithStreamingResponse(self._client.messages) + + @cached_property + def config(self) -> config.ConfigResourceWithStreamingResponse: + from .resources.config import ConfigResourceWithStreamingResponse + + return ConfigResourceWithStreamingResponse(self._client.config) + + @cached_property + def batches(self) -> batches.BatchesResourceWithStreamingResponse: + from .resources.batches import BatchesResourceWithStreamingResponse + + return BatchesResourceWithStreamingResponse(self._client.batches) class AsyncBlooioWithStreamedResponse: + _client: AsyncBlooio + def __init__(self, client: AsyncBlooio) -> None: - self.me = me.AsyncMeResourceWithStreamingResponse(client.me) - self.contacts = contacts.AsyncContactsResourceWithStreamingResponse(client.contacts) - self.messages = messages.AsyncMessagesResourceWithStreamingResponse(client.messages) - self.config = config.AsyncConfigResourceWithStreamingResponse(client.config) - self.batches = batches.AsyncBatchesResourceWithStreamingResponse(client.batches) + self._client = client + + @cached_property + def me(self) -> me.AsyncMeResourceWithStreamingResponse: + from .resources.me import AsyncMeResourceWithStreamingResponse + + return AsyncMeResourceWithStreamingResponse(self._client.me) + + @cached_property + def contacts(self) -> contacts.AsyncContactsResourceWithStreamingResponse: + from .resources.contacts import AsyncContactsResourceWithStreamingResponse + + return AsyncContactsResourceWithStreamingResponse(self._client.contacts) + + @cached_property + def messages(self) -> messages.AsyncMessagesResourceWithStreamingResponse: + from .resources.messages import AsyncMessagesResourceWithStreamingResponse + + return AsyncMessagesResourceWithStreamingResponse(self._client.messages) + + @cached_property + def config(self) -> config.AsyncConfigResourceWithStreamingResponse: + from .resources.config import AsyncConfigResourceWithStreamingResponse + + return AsyncConfigResourceWithStreamingResponse(self._client.config) + + @cached_property + def batches(self) -> batches.AsyncBatchesResourceWithStreamingResponse: + from .resources.batches import AsyncBatchesResourceWithStreamingResponse + + return AsyncBatchesResourceWithStreamingResponse(self._client.batches) Client = Blooio From b6502acc9bf7d875b8c122b4560ca6f592ccb07f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 18 Dec 2025 07:00:13 +0000 Subject: [PATCH 3/5] fix: use async_to_httpx_files in patch method --- src/blooio/_base_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blooio/_base_client.py b/src/blooio/_base_client.py index f85e4f3..3293983 100644 --- a/src/blooio/_base_client.py +++ b/src/blooio/_base_client.py @@ -1774,7 +1774,7 @@ async def patch( options: RequestOptions = {}, ) -> ResponseT: opts = FinalRequestOptions.construct( - method="patch", url=path, json_data=body, files=to_httpx_files(files), **options + method="patch", url=path, json_data=body, files=await async_to_httpx_files(files), **options ) return await self.request(cast_to, opts) From 18f419d1a0fa01d20d635c848ed33f78d0fefda9 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 19 Dec 2025 06:07:21 +0000 Subject: [PATCH 4/5] chore(internal): add `--fix` argument to lint script --- scripts/lint | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/scripts/lint b/scripts/lint index b9f04e2..fafdf3e 100755 --- a/scripts/lint +++ b/scripts/lint @@ -4,8 +4,13 @@ set -e cd "$(dirname "$0")/.." -echo "==> Running lints" -rye run lint +if [ "$1" = "--fix" ]; then + echo "==> Running lints with --fix" + rye run fix:ruff +else + echo "==> Running lints" + rye run lint +fi echo "==> Making sure it imports" rye run python -c 'import blooio' From d87b7a42ccc916af27a6a3bcb4796cc1d5ff2506 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 19 Dec 2025 06:07:37 +0000 Subject: [PATCH 5/5] release: 1.0.5 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 15 +++++++++++++++ pyproject.toml | 2 +- src/blooio/_version.py | 2 +- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 80d368a..1214610 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.0.4" + ".": "1.0.5" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 65ccbff..68fe48c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## 1.0.5 (2025-12-19) + +Full Changelog: [v1.0.4...v1.0.5](https://github.com/Blooio/blooio-python-sdk/compare/v1.0.4...v1.0.5) + +### Bug Fixes + +* use async_to_httpx_files in patch method ([b6502ac](https://github.com/Blooio/blooio-python-sdk/commit/b6502acc9bf7d875b8c122b4560ca6f592ccb07f)) + + +### Chores + +* **internal:** add `--fix` argument to lint script ([18f419d](https://github.com/Blooio/blooio-python-sdk/commit/18f419d1a0fa01d20d635c848ed33f78d0fefda9)) +* **internal:** add missing files argument to base client ([ba6fc65](https://github.com/Blooio/blooio-python-sdk/commit/ba6fc65657b77abc6fc59aed3053e3d3d4c6ec84)) +* speedup initial import ([512dd39](https://github.com/Blooio/blooio-python-sdk/commit/512dd3980296e17dcc7e02f508a295ff5e498d8d)) + ## 1.0.4 (2025-12-09) Full Changelog: [v1.0.3...v1.0.4](https://github.com/Blooio/blooio-python-sdk/compare/v1.0.3...v1.0.4) diff --git a/pyproject.toml b/pyproject.toml index 102bd61..c399c78 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "blooio" -version = "1.0.4" +version = "1.0.5" description = "The official Python library for the blooio API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/blooio/_version.py b/src/blooio/_version.py index d1b9fff..dcf7039 100644 --- a/src/blooio/_version.py +++ b/src/blooio/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "blooio" -__version__ = "1.0.4" # x-release-please-version +__version__ = "1.0.5" # x-release-please-version