From 3741b42c7ab0c75897bb5cd753b1ce3b323686d2 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 01:10:53 +0000 Subject: [PATCH 01/10] chore: update SDK settings --- .stats.yml | 2 +- README.md | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/.stats.yml b/.stats.yml index 50bd7a1..9b53ab5 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 23 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper%2Fbeeper-desktop-api-ee25e67fc85ccc86cedb2ca0865385709877582132103e0afa68d7b43551784a.yml openapi_spec_hash: d41fd99c9a8645a1fd69c519cd25a637 -config_hash: abdcaeff62a619bdf25d727cdeacf3b0 +config_hash: bd091e75baa300de3a05731fbd7f479e diff --git a/README.md b/README.md index c0c9be9..a48acff 100644 --- a/README.md +++ b/README.md @@ -23,13 +23,10 @@ The REST API documentation can be found on [developers.beeper.com](https://devel ## Installation ```sh -# install from the production repo -pip install git+ssh://git@github.com/beeper/desktop-api-python.git +# install from PyPI +pip install beeper_desktop_api ``` -> [!NOTE] -> Once this package is [published to PyPI](https://www.stainless.com/docs/guides/publish), this will become: `pip install beeper_desktop_api` - ## Usage The full API of this library can be found in [api.md](api.md). @@ -90,8 +87,8 @@ By default, the async client uses `httpx` for HTTP requests. However, for improv You can enable this by installing `aiohttp`: ```sh -# install from the production repo -pip install 'beeper_desktop_api[aiohttp] @ git+ssh://git@github.com/beeper/desktop-api-python.git' +# install from PyPI +pip install beeper_desktop_api[aiohttp] ``` Then you can enable it by instantiating the client with `http_client=DefaultAioHttpClient()`: From 207b92626fbbd0ea68eb915be50b776ed84673a8 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 01:11:11 +0000 Subject: [PATCH 02/10] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 9b53ab5..776042b 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 23 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper%2Fbeeper-desktop-api-ee25e67fc85ccc86cedb2ca0865385709877582132103e0afa68d7b43551784a.yml openapi_spec_hash: d41fd99c9a8645a1fd69c519cd25a637 -config_hash: bd091e75baa300de3a05731fbd7f479e +config_hash: 07a9227b2e53d5bf022c964ac30d72fa From 223108ddc2f84269df96dd8abf6787d8e45c02e6 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 01:21:27 +0000 Subject: [PATCH 03/10] feat(api): manual updates --- .stats.yml | 6 +- README.md | 17 +++-- .../resources/chats/chats.py | 4 +- .../types/chat_create_params.py | 72 +++++++++---------- tests/api_resources/test_chats.py | 48 ++++++++++--- 5 files changed, 88 insertions(+), 59 deletions(-) diff --git a/.stats.yml b/.stats.yml index 776042b..768e7e7 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 23 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper%2Fbeeper-desktop-api-ee25e67fc85ccc86cedb2ca0865385709877582132103e0afa68d7b43551784a.yml -openapi_spec_hash: d41fd99c9a8645a1fd69c519cd25a637 -config_hash: 07a9227b2e53d5bf022c964ac30d72fa +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper%2Fbeeper-desktop-api-1b8324f05cd39e88cfc36b9b86a868b6f7e0c9e0827bb30d70a6d875c151ae52.yml +openapi_spec_hash: 41410e315f6a3d0be787ece9e4fcb96a +config_hash: abdcaeff62a619bdf25d727cdeacf3b0 diff --git a/README.md b/README.md index a48acff..17e8229 100644 --- a/README.md +++ b/README.md @@ -23,10 +23,13 @@ The REST API documentation can be found on [developers.beeper.com](https://devel ## Installation ```sh -# install from PyPI -pip install beeper_desktop_api +# install from the production repo +pip install git+ssh://git@github.com/beeper/desktop-api-python.git ``` +> [!NOTE] +> Once this package is [published to PyPI](https://www.stainless.com/docs/guides/publish), this will become: `pip install beeper_desktop_api` + ## Usage The full API of this library can be found in [api.md](api.md). @@ -87,8 +90,8 @@ By default, the async client uses `httpx` for HTTP requests. However, for improv You can enable this by installing `aiohttp`: ```sh -# install from PyPI -pip install beeper_desktop_api[aiohttp] +# install from the production repo +pip install 'beeper_desktop_api[aiohttp] @ git+ssh://git@github.com/beeper/desktop-api-python.git' ``` Then you can enable it by instantiating the client with `http_client=DefaultAioHttpClient()`: @@ -215,10 +218,10 @@ from beeper_desktop_api import BeeperDesktop client = BeeperDesktop() -client.chats.reminders.create( - chat_id="!NCdzlIaMjZUmvmvyHU:beeper.com", - reminder={"remind_at_ms": 0}, +chat = client.chats.create( + chat={"account_id": "accountID"}, ) +print(chat.user) ``` ## File uploads diff --git a/src/beeper_desktop_api/resources/chats/chats.py b/src/beeper_desktop_api/resources/chats/chats.py index 4682744..75b6c33 100644 --- a/src/beeper_desktop_api/resources/chats/chats.py +++ b/src/beeper_desktop_api/resources/chats/chats.py @@ -79,7 +79,7 @@ def with_streaming_response(self) -> ChatsResourceWithStreamingResponse: def create( self, *, - chat: chat_create_params.Chat | Omit = omit, + chat: chat_create_params.Chat, # 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, @@ -383,7 +383,7 @@ def with_streaming_response(self) -> AsyncChatsResourceWithStreamingResponse: async def create( self, *, - chat: chat_create_params.Chat | Omit = omit, + chat: chat_create_params.Chat, # 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, diff --git a/src/beeper_desktop_api/types/chat_create_params.py b/src/beeper_desktop_api/types/chat_create_params.py index b0314d5..0ba872c 100644 --- a/src/beeper_desktop_api/types/chat_create_params.py +++ b/src/beeper_desktop_api/types/chat_create_params.py @@ -2,44 +2,23 @@ from __future__ import annotations -from typing import Union -from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict +from typing_extensions import Literal, Required, Annotated, TypedDict from .._types import SequenceNotStr from .._utils import PropertyInfo -__all__ = ["ChatCreateParams", "Chat", "ChatUnionMember0", "ChatUnionMember1", "ChatUnionMember1User"] +__all__ = ["ChatCreateParams", "Chat", "ChatUser"] class ChatCreateParams(TypedDict, total=False): - chat: Chat + chat: Required[Chat] -class ChatUnionMember0(TypedDict, total=False): - account_id: Required[Annotated[str, PropertyInfo(alias="accountID")]] - """Account to create the chat on.""" - - participant_ids: Required[Annotated[SequenceNotStr[str], PropertyInfo(alias="participantIDs")]] - """User IDs to include in the new chat.""" +class ChatUser(TypedDict, total=False): + """Required when mode='start'. - type: Required[Literal["single", "group"]] + Merged user-like contact payload used to resolve the best identifier. """ - Chat type to create: 'single' requires exactly one participantID; 'group' - supports multiple participants and optional title. - """ - - message_text: Annotated[str, PropertyInfo(alias="messageText")] - """Optional first message content if the platform requires it to create the chat.""" - - mode: Literal["create"] - """Create mode. Defaults to 'create' when omitted.""" - - title: str - """Optional title for group chats; ignored for single chats on most platforms.""" - - -class ChatUnionMember1User(TypedDict, total=False): - """Merged user-like contact payload used to resolve the best identifier.""" id: str """Known user ID when available.""" @@ -57,21 +36,40 @@ class ChatUnionMember1User(TypedDict, total=False): """Username/handle candidate.""" -class ChatUnionMember1(TypedDict, total=False): +class Chat(TypedDict, total=False): account_id: Required[Annotated[str, PropertyInfo(alias="accountID")]] - """Account to start the chat on.""" - - mode: Required[Literal["start"]] - """Start mode for resolving/creating a direct chat from merged contact data.""" - - user: Required[ChatUnionMember1User] - """Merged user-like contact payload used to resolve the best identifier.""" + """Account to create or start the chat on.""" allow_invite: Annotated[bool, PropertyInfo(alias="allowInvite")] - """Whether invite-based DM creation is allowed when required by the platform.""" + """Whether invite-based DM creation is allowed when required by the platform. + + Used for mode='start'. + """ message_text: Annotated[str, PropertyInfo(alias="messageText")] """Optional first message content if the platform requires it to create the chat.""" + mode: Literal["create", "start"] + """Operation mode. Defaults to 'create' when omitted.""" + + participant_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="participantIDs")] + """Required when mode='create'. User IDs to include in the new chat.""" + + title: str + """ + Optional title for group chats when mode='create'; ignored for single chats on + most platforms. + """ + + type: Literal["single", "group"] + """Required when mode='create'. + + 'single' requires exactly one participantID; 'group' supports multiple + participants and optional title. + """ + + user: ChatUser + """Required when mode='start'. -Chat: TypeAlias = Union[ChatUnionMember0, ChatUnionMember1] + Merged user-like contact payload used to resolve the best identifier. + """ diff --git a/tests/api_resources/test_chats.py b/tests/api_resources/test_chats.py index ba28f71..74b7ab4 100644 --- a/tests/api_resources/test_chats.py +++ b/tests/api_resources/test_chats.py @@ -25,7 +25,9 @@ class TestChats: @parametrize def test_method_create(self, client: BeeperDesktop) -> None: - chat = client.chats.create() + chat = client.chats.create( + chat={"account_id": "accountID"}, + ) assert_matches_type(ChatCreateResponse, chat, path=["response"]) @parametrize @@ -33,18 +35,28 @@ def test_method_create_with_all_params(self, client: BeeperDesktop) -> None: chat = client.chats.create( chat={ "account_id": "accountID", - "participant_ids": ["string"], - "type": "single", + "allow_invite": True, "message_text": "messageText", "mode": "create", + "participant_ids": ["string"], "title": "title", + "type": "single", + "user": { + "id": "id", + "email": "email", + "full_name": "fullName", + "phone_number": "phoneNumber", + "username": "username", + }, }, ) assert_matches_type(ChatCreateResponse, chat, path=["response"]) @parametrize def test_raw_response_create(self, client: BeeperDesktop) -> None: - response = client.chats.with_raw_response.create() + response = client.chats.with_raw_response.create( + chat={"account_id": "accountID"}, + ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -53,7 +65,9 @@ def test_raw_response_create(self, client: BeeperDesktop) -> None: @parametrize def test_streaming_response_create(self, client: BeeperDesktop) -> None: - with client.chats.with_streaming_response.create() as response: + with client.chats.with_streaming_response.create( + chat={"account_id": "accountID"}, + ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -245,7 +259,9 @@ class TestAsyncChats: @parametrize async def test_method_create(self, async_client: AsyncBeeperDesktop) -> None: - chat = await async_client.chats.create() + chat = await async_client.chats.create( + chat={"account_id": "accountID"}, + ) assert_matches_type(ChatCreateResponse, chat, path=["response"]) @parametrize @@ -253,18 +269,28 @@ async def test_method_create_with_all_params(self, async_client: AsyncBeeperDesk chat = await async_client.chats.create( chat={ "account_id": "accountID", - "participant_ids": ["string"], - "type": "single", + "allow_invite": True, "message_text": "messageText", "mode": "create", + "participant_ids": ["string"], "title": "title", + "type": "single", + "user": { + "id": "id", + "email": "email", + "full_name": "fullName", + "phone_number": "phoneNumber", + "username": "username", + }, }, ) assert_matches_type(ChatCreateResponse, chat, path=["response"]) @parametrize async def test_raw_response_create(self, async_client: AsyncBeeperDesktop) -> None: - response = await async_client.chats.with_raw_response.create() + response = await async_client.chats.with_raw_response.create( + chat={"account_id": "accountID"}, + ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -273,7 +299,9 @@ async def test_raw_response_create(self, async_client: AsyncBeeperDesktop) -> No @parametrize async def test_streaming_response_create(self, async_client: AsyncBeeperDesktop) -> None: - async with async_client.chats.with_streaming_response.create() as response: + async with async_client.chats.with_streaming_response.create( + chat={"account_id": "accountID"}, + ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" From 70593f0416d4ed7251957c9fcdb5805e570b2577 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 04:19:59 +0000 Subject: [PATCH 04/10] chore: update mock server docs --- CONTRIBUTING.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 81bc94a..08c3ec2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -88,8 +88,7 @@ $ pip install ./path-to-wheel-file.whl Most tests require you to [set up a mock server](https://github.com/stoplightio/prism) against the OpenAPI spec to run the tests. ```sh -# you will need npm installed -$ npx prism mock path/to/your/openapi.yml +$ ./scripts/mock ``` ```sh From e590c4f536300cd773a460f792c3c6fa314926a5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 14:18:58 +0000 Subject: [PATCH 05/10] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 768e7e7..3a78cf5 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 23 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper%2Fbeeper-desktop-api-1b8324f05cd39e88cfc36b9b86a868b6f7e0c9e0827bb30d70a6d875c151ae52.yml -openapi_spec_hash: 41410e315f6a3d0be787ece9e4fcb96a +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper%2Fbeeper-desktop-api-774bb08472b6bb14c280fe5b767925675516b5c8ccc0b89b5abd7ac7bc30fe5a.yml +openapi_spec_hash: ddd1ce1f334b45206ac008b0f5296842 config_hash: abdcaeff62a619bdf25d727cdeacf3b0 From f035829111c303751f975888188a5ac79457944a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 14:19:50 +0000 Subject: [PATCH 06/10] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 3a78cf5..b40afd8 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 23 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper%2Fbeeper-desktop-api-774bb08472b6bb14c280fe5b767925675516b5c8ccc0b89b5abd7ac7bc30fe5a.yml openapi_spec_hash: ddd1ce1f334b45206ac008b0f5296842 -config_hash: abdcaeff62a619bdf25d727cdeacf3b0 +config_hash: cd9eef64c1202fa937a22172b0218447 From 5d9ff0eb3ee775b272ecaca6b044e816c992325b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 14:42:20 +0000 Subject: [PATCH 07/10] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index b40afd8..8ec4701 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 23 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper%2Fbeeper-desktop-api-774bb08472b6bb14c280fe5b767925675516b5c8ccc0b89b5abd7ac7bc30fe5a.yml openapi_spec_hash: ddd1ce1f334b45206ac008b0f5296842 -config_hash: cd9eef64c1202fa937a22172b0218447 +config_hash: b5ac0c1579dfe6257bcdb84cfd1002fc From c77412c3d4daa460f8901f715a9f59dc1bfa3970 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 14:52:14 +0000 Subject: [PATCH 08/10] feat(api): api update --- .stats.yml | 4 ++-- src/beeper_desktop_api/resources/messages.py | 4 ++-- src/beeper_desktop_api/types/message_search_params.py | 2 +- src/beeper_desktop_api/types/shared/error.py | 10 +++++----- tests/api_resources/test_messages.py | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.stats.yml b/.stats.yml index 8ec4701..5a6113f 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 23 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper%2Fbeeper-desktop-api-774bb08472b6bb14c280fe5b767925675516b5c8ccc0b89b5abd7ac7bc30fe5a.yml -openapi_spec_hash: ddd1ce1f334b45206ac008b0f5296842 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper%2Fbeeper-desktop-api-4acef56b00be513f305543096fdd407e6947f0a5ad268ab2e627ff30b37a75db.yml +openapi_spec_hash: e876d796b6c25f18577f6be3944bf7d9 config_hash: b5ac0c1579dfe6257bcdb84cfd1002fc diff --git a/src/beeper_desktop_api/resources/messages.py b/src/beeper_desktop_api/resources/messages.py index 63ad8e1..b97c7a0 100644 --- a/src/beeper_desktop_api/resources/messages.py +++ b/src/beeper_desktop_api/resources/messages.py @@ -163,7 +163,7 @@ def search( limit: int | Omit = omit, media_types: List[Literal["any", "video", "image", "link", "file"]] | Omit = omit, query: str | Omit = omit, - sender: Union[Literal["me", "others"], str] | Omit = omit, + sender: str | 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. extra_headers: Headers | None = None, @@ -439,7 +439,7 @@ def search( limit: int | Omit = omit, media_types: List[Literal["any", "video", "image", "link", "file"]] | Omit = omit, query: str | Omit = omit, - sender: Union[Literal["me", "others"], str] | Omit = omit, + sender: str | 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. extra_headers: Headers | None = None, diff --git a/src/beeper_desktop_api/types/message_search_params.py b/src/beeper_desktop_api/types/message_search_params.py index 3ba609d..e9bab35 100644 --- a/src/beeper_desktop_api/types/message_search_params.py +++ b/src/beeper_desktop_api/types/message_search_params.py @@ -74,7 +74,7 @@ class MessageSearchParams(TypedDict, total=False): only by other parameters. """ - sender: Union[Literal["me", "others"], str] + sender: str """ Filter by sender: 'me' (messages sent by the authenticated user), 'others' (messages sent by others), or a specific user ID string (user.id). diff --git a/src/beeper_desktop_api/types/shared/error.py b/src/beeper_desktop_api/types/shared/error.py index df9fdbb..17c2409 100644 --- a/src/beeper_desktop_api/types/shared/error.py +++ b/src/beeper_desktop_api/types/shared/error.py @@ -5,10 +5,10 @@ from ..._models import BaseModel -__all__ = ["Error", "Details", "DetailsIssues", "DetailsIssuesIssue"] +__all__ = ["Error", "Details", "DetailsValidationDetails", "DetailsValidationDetailsIssue"] -class DetailsIssuesIssue(BaseModel): +class DetailsValidationDetailsIssue(BaseModel): code: str """Validation issue code""" @@ -19,14 +19,14 @@ class DetailsIssuesIssue(BaseModel): """Path pointing to the invalid field within the payload""" -class DetailsIssues(BaseModel): +class DetailsValidationDetails(BaseModel): """Validation error details""" - issues: List[DetailsIssuesIssue] + issues: List[DetailsValidationDetailsIssue] """List of validation issues""" -Details: TypeAlias = Union[DetailsIssues, Dict[str, Optional[object]], Optional[object]] +Details: TypeAlias = Union[DetailsValidationDetails, Dict[str, Optional[object]], Optional[object]] class Error(BaseModel): diff --git a/tests/api_resources/test_messages.py b/tests/api_resources/test_messages.py index b6c3900..a167221 100644 --- a/tests/api_resources/test_messages.py +++ b/tests/api_resources/test_messages.py @@ -146,7 +146,7 @@ def test_method_search_with_all_params(self, client: BeeperDesktop) -> None: limit=20, media_types=["any"], query="dinner", - sender="me", + sender="sender", ) assert_matches_type(SyncCursorSearch[Message], message, path=["response"]) @@ -357,7 +357,7 @@ async def test_method_search_with_all_params(self, async_client: AsyncBeeperDesk limit=20, media_types=["any"], query="dinner", - sender="me", + sender="sender", ) assert_matches_type(AsyncCursorSearch[Message], message, path=["response"]) From 4f6c2685f00a7fd4f1db0b34faa6e354a0f7e220 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 14:58:08 +0000 Subject: [PATCH 09/10] feat(api): api update --- .stats.yml | 2 +- README.md | 3 +- .../resources/chats/chats.py | 86 ++++++++++++++++++- .../types/chat_create_params.py | 52 ++++++----- tests/api_resources/test_chats.py | 68 +++++++-------- 5 files changed, 141 insertions(+), 70 deletions(-) diff --git a/.stats.yml b/.stats.yml index 5a6113f..56c368e 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 23 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper%2Fbeeper-desktop-api-4acef56b00be513f305543096fdd407e6947f0a5ad268ab2e627ff30b37a75db.yml openapi_spec_hash: e876d796b6c25f18577f6be3944bf7d9 -config_hash: b5ac0c1579dfe6257bcdb84cfd1002fc +config_hash: 659111d4e28efa599b5f800619ed79c2 diff --git a/README.md b/README.md index 17e8229..b42ad75 100644 --- a/README.md +++ b/README.md @@ -219,7 +219,8 @@ from beeper_desktop_api import BeeperDesktop client = BeeperDesktop() chat = client.chats.create( - chat={"account_id": "accountID"}, + account_id="accountID", + user={}, ) print(chat.user) ``` diff --git a/src/beeper_desktop_api/resources/chats/chats.py b/src/beeper_desktop_api/resources/chats/chats.py index 75b6c33..6a3cdb0 100644 --- a/src/beeper_desktop_api/resources/chats/chats.py +++ b/src/beeper_desktop_api/resources/chats/chats.py @@ -79,7 +79,14 @@ def with_streaming_response(self) -> ChatsResourceWithStreamingResponse: def create( self, *, - chat: chat_create_params.Chat, + account_id: str, + allow_invite: bool | Omit = omit, + message_text: str | Omit = omit, + mode: Literal["create", "start"] | Omit = omit, + participant_ids: SequenceNotStr[str] | Omit = omit, + title: str | Omit = omit, + type: Literal["single", "group"] | Omit = omit, + user: chat_create_params.User | 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. extra_headers: Headers | None = None, @@ -92,6 +99,26 @@ def create( user data (mode='start'). Args: + account_id: Account to create or start the chat on. + + allow_invite: Whether invite-based DM creation is allowed when required by the platform. Used + for mode='start'. + + message_text: Optional first message content if the platform requires it to create the chat. + + mode: Operation mode. Defaults to 'create' when omitted. + + participant_ids: Required when mode='create'. User IDs to include in the new chat. + + title: Optional title for group chats when mode='create'; ignored for single chats on + most platforms. + + type: Required when mode='create'. 'single' requires exactly one participantID; + 'group' supports multiple participants and optional title. + + user: Required when mode='start'. Merged user-like contact payload used to resolve the + best identifier. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -102,7 +129,19 @@ def create( """ return self._post( "/v1/chats", - body=maybe_transform(chat, chat_create_params.ChatCreateParams), + body=maybe_transform( + { + "account_id": account_id, + "allow_invite": allow_invite, + "message_text": message_text, + "mode": mode, + "participant_ids": participant_ids, + "title": title, + "type": type, + "user": user, + }, + chat_create_params.ChatCreateParams, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -383,7 +422,14 @@ def with_streaming_response(self) -> AsyncChatsResourceWithStreamingResponse: async def create( self, *, - chat: chat_create_params.Chat, + account_id: str, + allow_invite: bool | Omit = omit, + message_text: str | Omit = omit, + mode: Literal["create", "start"] | Omit = omit, + participant_ids: SequenceNotStr[str] | Omit = omit, + title: str | Omit = omit, + type: Literal["single", "group"] | Omit = omit, + user: chat_create_params.User | 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. extra_headers: Headers | None = None, @@ -396,6 +442,26 @@ async def create( user data (mode='start'). Args: + account_id: Account to create or start the chat on. + + allow_invite: Whether invite-based DM creation is allowed when required by the platform. Used + for mode='start'. + + message_text: Optional first message content if the platform requires it to create the chat. + + mode: Operation mode. Defaults to 'create' when omitted. + + participant_ids: Required when mode='create'. User IDs to include in the new chat. + + title: Optional title for group chats when mode='create'; ignored for single chats on + most platforms. + + type: Required when mode='create'. 'single' requires exactly one participantID; + 'group' supports multiple participants and optional title. + + user: Required when mode='start'. Merged user-like contact payload used to resolve the + best identifier. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -406,7 +472,19 @@ async def create( """ return await self._post( "/v1/chats", - body=await async_maybe_transform(chat, chat_create_params.ChatCreateParams), + body=await async_maybe_transform( + { + "account_id": account_id, + "allow_invite": allow_invite, + "message_text": message_text, + "mode": mode, + "participant_ids": participant_ids, + "title": title, + "type": type, + "user": user, + }, + chat_create_params.ChatCreateParams, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/beeper_desktop_api/types/chat_create_params.py b/src/beeper_desktop_api/types/chat_create_params.py index 0ba872c..93229c1 100644 --- a/src/beeper_desktop_api/types/chat_create_params.py +++ b/src/beeper_desktop_api/types/chat_create_params.py @@ -7,36 +7,10 @@ from .._types import SequenceNotStr from .._utils import PropertyInfo -__all__ = ["ChatCreateParams", "Chat", "ChatUser"] +__all__ = ["ChatCreateParams", "User"] class ChatCreateParams(TypedDict, total=False): - chat: Required[Chat] - - -class ChatUser(TypedDict, total=False): - """Required when mode='start'. - - Merged user-like contact payload used to resolve the best identifier. - """ - - id: str - """Known user ID when available.""" - - email: str - """Email candidate.""" - - full_name: Annotated[str, PropertyInfo(alias="fullName")] - """Display name hint used for ranking only.""" - - phone_number: Annotated[str, PropertyInfo(alias="phoneNumber")] - """Phone number candidate (E.164 preferred).""" - - username: str - """Username/handle candidate.""" - - -class Chat(TypedDict, total=False): account_id: Required[Annotated[str, PropertyInfo(alias="accountID")]] """Account to create or start the chat on.""" @@ -68,8 +42,30 @@ class Chat(TypedDict, total=False): participants and optional title. """ - user: ChatUser + user: User """Required when mode='start'. Merged user-like contact payload used to resolve the best identifier. """ + + +class User(TypedDict, total=False): + """Required when mode='start'. + + Merged user-like contact payload used to resolve the best identifier. + """ + + id: str + """Known user ID when available.""" + + email: str + """Email candidate.""" + + full_name: Annotated[str, PropertyInfo(alias="fullName")] + """Display name hint used for ranking only.""" + + phone_number: Annotated[str, PropertyInfo(alias="phoneNumber")] + """Phone number candidate (E.164 preferred).""" + + username: str + """Username/handle candidate.""" diff --git a/tests/api_resources/test_chats.py b/tests/api_resources/test_chats.py index 74b7ab4..b899add 100644 --- a/tests/api_resources/test_chats.py +++ b/tests/api_resources/test_chats.py @@ -26,28 +26,26 @@ class TestChats: @parametrize def test_method_create(self, client: BeeperDesktop) -> None: chat = client.chats.create( - chat={"account_id": "accountID"}, + account_id="accountID", ) assert_matches_type(ChatCreateResponse, chat, path=["response"]) @parametrize def test_method_create_with_all_params(self, client: BeeperDesktop) -> None: chat = client.chats.create( - chat={ - "account_id": "accountID", - "allow_invite": True, - "message_text": "messageText", - "mode": "create", - "participant_ids": ["string"], - "title": "title", - "type": "single", - "user": { - "id": "id", - "email": "email", - "full_name": "fullName", - "phone_number": "phoneNumber", - "username": "username", - }, + account_id="accountID", + allow_invite=True, + message_text="messageText", + mode="create", + participant_ids=["string"], + title="title", + type="single", + user={ + "id": "id", + "email": "email", + "full_name": "fullName", + "phone_number": "phoneNumber", + "username": "username", }, ) assert_matches_type(ChatCreateResponse, chat, path=["response"]) @@ -55,7 +53,7 @@ def test_method_create_with_all_params(self, client: BeeperDesktop) -> None: @parametrize def test_raw_response_create(self, client: BeeperDesktop) -> None: response = client.chats.with_raw_response.create( - chat={"account_id": "accountID"}, + account_id="accountID", ) assert response.is_closed is True @@ -66,7 +64,7 @@ def test_raw_response_create(self, client: BeeperDesktop) -> None: @parametrize def test_streaming_response_create(self, client: BeeperDesktop) -> None: with client.chats.with_streaming_response.create( - chat={"account_id": "accountID"}, + account_id="accountID", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -260,28 +258,26 @@ class TestAsyncChats: @parametrize async def test_method_create(self, async_client: AsyncBeeperDesktop) -> None: chat = await async_client.chats.create( - chat={"account_id": "accountID"}, + account_id="accountID", ) assert_matches_type(ChatCreateResponse, chat, path=["response"]) @parametrize async def test_method_create_with_all_params(self, async_client: AsyncBeeperDesktop) -> None: chat = await async_client.chats.create( - chat={ - "account_id": "accountID", - "allow_invite": True, - "message_text": "messageText", - "mode": "create", - "participant_ids": ["string"], - "title": "title", - "type": "single", - "user": { - "id": "id", - "email": "email", - "full_name": "fullName", - "phone_number": "phoneNumber", - "username": "username", - }, + account_id="accountID", + allow_invite=True, + message_text="messageText", + mode="create", + participant_ids=["string"], + title="title", + type="single", + user={ + "id": "id", + "email": "email", + "full_name": "fullName", + "phone_number": "phoneNumber", + "username": "username", }, ) assert_matches_type(ChatCreateResponse, chat, path=["response"]) @@ -289,7 +285,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncBeeperDesk @parametrize async def test_raw_response_create(self, async_client: AsyncBeeperDesktop) -> None: response = await async_client.chats.with_raw_response.create( - chat={"account_id": "accountID"}, + account_id="accountID", ) assert response.is_closed is True @@ -300,7 +296,7 @@ async def test_raw_response_create(self, async_client: AsyncBeeperDesktop) -> No @parametrize async def test_streaming_response_create(self, async_client: AsyncBeeperDesktop) -> None: async with async_client.chats.with_streaming_response.create( - chat={"account_id": "accountID"}, + account_id="accountID", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" From 482049df24c1474a2e23cb2977e38ca1ae625b52 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 14:58:43 +0000 Subject: [PATCH 10/10] release: 4.3.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 16 ++++++++++++++++ pyproject.toml | 2 +- src/beeper_desktop_api/_version.py | 2 +- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index bd7f384..29102ae 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.2.0" + ".": "4.3.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 757844b..d5ee4c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +## 4.3.0 (2026-02-20) + +Full Changelog: [v4.2.0...v4.3.0](https://github.com/beeper/desktop-api-python/compare/v4.2.0...v4.3.0) + +### Features + +* **api:** api update ([4f6c268](https://github.com/beeper/desktop-api-python/commit/4f6c2685f00a7fd4f1db0b34faa6e354a0f7e220)) +* **api:** api update ([c77412c](https://github.com/beeper/desktop-api-python/commit/c77412c3d4daa460f8901f715a9f59dc1bfa3970)) +* **api:** manual updates ([223108d](https://github.com/beeper/desktop-api-python/commit/223108ddc2f84269df96dd8abf6787d8e45c02e6)) + + +### Chores + +* update mock server docs ([70593f0](https://github.com/beeper/desktop-api-python/commit/70593f0416d4ed7251957c9fcdb5805e570b2577)) +* update SDK settings ([3741b42](https://github.com/beeper/desktop-api-python/commit/3741b42c7ab0c75897bb5cd753b1ce3b323686d2)) + ## 4.2.0 (2026-02-20) Full Changelog: [v4.1.296...v4.2.0](https://github.com/beeper/desktop-api-python/compare/v4.1.296...v4.2.0) diff --git a/pyproject.toml b/pyproject.toml index 96e553a..089b317 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "beeper_desktop_api" -version = "4.2.0" +version = "4.3.0" description = "The official Python library for the beeperdesktop API" dynamic = ["readme"] license = "MIT" diff --git a/src/beeper_desktop_api/_version.py b/src/beeper_desktop_api/_version.py index 9e1f20a..1bc95e4 100644 --- a/src/beeper_desktop_api/_version.py +++ b/src/beeper_desktop_api/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "beeper_desktop_api" -__version__ = "4.2.0" # x-release-please-version +__version__ = "4.3.0" # x-release-please-version