diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1ca0ca2..ed91b37 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: runs-on: ${{ github.repository == 'stainless-sdks/beeper-desktop-api-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rye run: | @@ -46,7 +46,7 @@ jobs: id-token: write runs-on: ${{ github.repository == 'stainless-sdks/beeper-desktop-api-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rye run: | @@ -67,7 +67,7 @@ jobs: github.repository == 'stainless-sdks/beeper-desktop-api-python' && !startsWith(github.ref, 'refs/heads/stl/') id: github-oidc - uses: actions/github-script@v8 + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: script: core.setOutput('github_token', await core.getIDToken()); @@ -87,7 +87,7 @@ jobs: runs-on: ${{ github.repository == 'stainless-sdks/beeper-desktop-api-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rye run: | diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 54361b5..4954ee6 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rye run: | diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml index 2d24407..0fe0ce0 100644 --- a/.github/workflows/release-doctor.yml +++ b/.github/workflows/release-doctor.yml @@ -12,7 +12,7 @@ jobs: if: github.repository == 'beeper/desktop-api-python' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next') steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Check release environment run: | diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 8e76abb..4808d97 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "5.0.0" + ".": "5.1.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 2dd3fee..a6a4fc8 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 30 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper/beeper-desktop-api-c08c14bb754b4cb0e02b21fabb680469368286be339dec0aaa8c69d04a1f021a.yml -openapi_spec_hash: a10246aaf7cdc33b682fc245bd5f893b -config_hash: 72f9d43b9b51a5da912e9f3730e53ae2 +configured_endpoints: 72 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper/beeper-desktop-api-0427b028ffd00b4f8b75084116f801658d0279117b2d0e522d1f257c998f1fd0.yml +openapi_spec_hash: af3ed0745fca6831cf2540c36050d4e6 +config_hash: fbf60dd7c0de7e17c7e2bb0ee09e9937 diff --git a/CHANGELOG.md b/CHANGELOG.md index 03fd832..0bce076 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 5.1.0 (2026-05-16) + +Full Changelog: [v5.0.0...v5.1.0](https://github.com/beeper/desktop-api-python/compare/v5.0.0...v5.1.0) + +### Features + +* **internal/types:** support eagerly validating pydantic iterators ([1850c8a](https://github.com/beeper/desktop-api-python/commit/1850c8a7b7d3e45407524a6ebffe902d4a3f8a71)) + + +### Bug Fixes + +* **client:** add missing f-string prefix in file type error message ([78424e2](https://github.com/beeper/desktop-api-python/commit/78424e24ad4e1f336f843222ff19bf70a50f073f)) + ## 5.0.0 (2026-05-06) Full Changelog: [v4.3.0...v5.0.0](https://github.com/beeper/desktop-api-python/compare/v4.3.0...v5.0.0) diff --git a/api.md b/api.md index 4818056..7ba1634 100644 --- a/api.md +++ b/api.md @@ -1,7 +1,7 @@ # Shared Types ```python -from beeper_desktop_api.types import Attachment, Error, Message, Reaction, User +from beeper_desktop_api.types import AppStateSnapshot, Attachment, Error, Message, Reaction, User ``` # BeeperDesktop @@ -42,6 +42,18 @@ Methods: - client.accounts.contacts.list(account_id, \*\*params) -> SyncCursorSearch[User] - client.accounts.contacts.search(account_id, \*\*params) -> ContactSearchResponse +# Bridges + +Types: + +```python +from beeper_desktop_api.types import BridgeAvailability, BridgeListResponse +``` + +Methods: + +- client.bridges.list() -> BridgeListResponse + # Chats Types: @@ -132,3 +144,266 @@ from beeper_desktop_api.types import InfoRetrieveResponse Methods: - client.info.retrieve() -> InfoRetrieveResponse + +# App + +Types: + +```python +from beeper_desktop_api.types import ( + LoginRegistrationRequiredResponse, + LoginResponse, + LoginResponseOutput, + RecoveryCodeResetResponse, + StartVerificationResponse, + StateMutationResponse, + AppStatusResponse, +) +``` + +Methods: + +- client.app.status() -> AppStatusResponse + +## Login + +Types: + +```python +from beeper_desktop_api.types.app import ( + LoginRegisterResponse, + LoginResponseResponse, + LoginStartResponse, +) +``` + +Methods: + +- client.app.login.email(\*\*params) -> object +- client.app.login.register(\*\*params) -> LoginRegisterResponse +- client.app.login.response(\*\*params) -> LoginResponseResponse +- client.app.login.start() -> LoginStartResponse + +## E2ee + +### RecoveryCode + +Types: + +```python +from beeper_desktop_api.types.app.e2ee import ( + RecoveryCodeMarkBackedUpResponse, + RecoveryCodeVerifyResponse, +) +``` + +Methods: + +- client.app.e2ee.recovery_code.mark_backed_up() -> RecoveryCodeMarkBackedUpResponse +- client.app.e2ee.recovery_code.verify(\*\*params) -> RecoveryCodeVerifyResponse + +#### Reset + +Types: + +```python +from beeper_desktop_api.types.app.e2ee.recovery_code import ( + ResetCreateResponse, + ResetConfirmResponse, +) +``` + +Methods: + +- client.app.e2ee.recovery_code.reset.create(\*\*params) -> ResetCreateResponse +- client.app.e2ee.recovery_code.reset.confirm(\*\*params) -> ResetConfirmResponse + +### Verification + +Types: + +```python +from beeper_desktop_api.types.app.e2ee import ( + VerificationCreateResponse, + VerificationAcceptResponse, + VerificationCancelResponse, +) +``` + +Methods: + +- client.app.e2ee.verification.create(\*\*params) -> VerificationCreateResponse +- client.app.e2ee.verification.accept(verification_id) -> VerificationAcceptResponse +- client.app.e2ee.verification.cancel(verification_id, \*\*params) -> VerificationCancelResponse + +#### Qr + +Types: + +```python +from beeper_desktop_api.types.app.e2ee.verification import QrConfirmScannedResponse, QrScanResponse +``` + +Methods: + +- client.app.e2ee.verification.qr.confirm_scanned(verification_id) -> QrConfirmScannedResponse +- client.app.e2ee.verification.qr.scan(\*\*params) -> QrScanResponse + +#### Sas + +Types: + +```python +from beeper_desktop_api.types.app.e2ee.verification import SaConfirmResponse, SaStartResponse +``` + +Methods: + +- client.app.e2ee.verification.sas.confirm(verification_id) -> SaConfirmResponse +- client.app.e2ee.verification.sas.start(verification_id) -> SaStartResponse + +# Matrix + +## Users + +Types: + +```python +from beeper_desktop_api.types.matrix import UserRetrieveProfileResponse +``` + +Methods: + +- client.matrix.users.retrieve_profile(user_id) -> UserRetrieveProfileResponse + +### AccountData + +Methods: + +- client.matrix.users.account_data.retrieve(type, \*, user_id) -> object +- client.matrix.users.account_data.update(type, \*, user_id, \*\*params) -> object + +## Rooms + +Types: + +```python +from beeper_desktop_api.types.matrix import RoomCreateResponse, RoomJoinResponse +``` + +Methods: + +- client.matrix.rooms.create(\*\*params) -> RoomCreateResponse +- client.matrix.rooms.join(room_id_or_alias, \*\*params) -> RoomJoinResponse +- client.matrix.rooms.leave(room_id, \*\*params) -> object + +### AccountData + +Methods: + +- client.matrix.rooms.account_data.retrieve(type, \*, user_id, room_id) -> object +- client.matrix.rooms.account_data.update(type, \*, user_id, room_id, \*\*params) -> object + +### State + +Types: + +```python +from beeper_desktop_api.types.matrix.rooms import StateRetrieveResponse, StateListResponse +``` + +Methods: + +- client.matrix.rooms.state.retrieve(state_key, \*, room_id, event_type, \*\*params) -> StateRetrieveResponse +- client.matrix.rooms.state.list(room_id) -> StateListResponse + +### Events + +Types: + +```python +from beeper_desktop_api.types.matrix.rooms import EventRetrieveResponse +``` + +Methods: + +- client.matrix.rooms.events.retrieve(event_id, \*, room_id) -> EventRetrieveResponse + +## Bridges + +### Auth + +Types: + +```python +from beeper_desktop_api.types.matrix.bridges import ( + AuthListFlowsResponse, + AuthListLoginsResponse, + AuthStartLoginResponse, + AuthSubmitCookiesResponse, + AuthSubmitUserInputResponse, + AuthWaitForStepResponse, + AuthWhoamiResponse, +) +``` + +Methods: + +- client.matrix.bridges.auth.list_flows(bridge_id) -> AuthListFlowsResponse +- client.matrix.bridges.auth.list_logins(bridge_id) -> AuthListLoginsResponse +- client.matrix.bridges.auth.logout(login_id, \*, bridge_id) -> object +- client.matrix.bridges.auth.start_login(flow_id, \*, bridge_id, \*\*params) -> AuthStartLoginResponse +- client.matrix.bridges.auth.submit_cookies(step_id, \*, bridge_id, login_process_id, \*\*params) -> AuthSubmitCookiesResponse +- client.matrix.bridges.auth.submit_user_input(step_id, \*, bridge_id, login_process_id, \*\*params) -> AuthSubmitUserInputResponse +- client.matrix.bridges.auth.wait_for_step(step_id, \*, bridge_id, login_process_id) -> AuthWaitForStepResponse +- client.matrix.bridges.auth.whoami(bridge_id) -> AuthWhoamiResponse + +### Contacts + +Types: + +```python +from beeper_desktop_api.types.matrix.bridges import ContactListResponse +``` + +Methods: + +- client.matrix.bridges.contacts.list(bridge_id, \*\*params) -> ContactListResponse + +### Users + +Types: + +```python +from beeper_desktop_api.types.matrix.bridges import UserResolveResponse, UserSearchResponse +``` + +Methods: + +- client.matrix.bridges.users.resolve(identifier, \*, bridge_id, \*\*params) -> UserResolveResponse +- client.matrix.bridges.users.search(bridge_id, \*\*params) -> UserSearchResponse + +### Rooms + +Types: + +```python +from beeper_desktop_api.types.matrix.bridges import RoomCreateDmResponse, RoomCreateGroupResponse +``` + +Methods: + +- client.matrix.bridges.rooms.create_dm(identifier, \*, bridge_id, \*\*params) -> RoomCreateDmResponse +- client.matrix.bridges.rooms.create_group(group_type, \*, bridge_id, \*\*params) -> RoomCreateGroupResponse + +### Capabilities + +Types: + +```python +from beeper_desktop_api.types.matrix.bridges import CapabilityRetrieveResponse +``` + +Methods: + +- client.matrix.bridges.capabilities.retrieve(bridge_id) -> CapabilityRetrieveResponse diff --git a/pyproject.toml b/pyproject.toml index 83d327e..5ce2088 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "beeper_desktop_api" -version = "5.0.0" +version = "5.1.0" description = "The official Python library for the beeperdesktop API" dynamic = ["readme"] license = "MIT" diff --git a/src/beeper_desktop_api/_client.py b/src/beeper_desktop_api/_client.py index 6c43fcb..9327a44 100644 --- a/src/beeper_desktop_api/_client.py +++ b/src/beeper_desktop_api/_client.py @@ -52,11 +52,14 @@ from .types.search_response import SearchResponse if TYPE_CHECKING: - from .resources import info, chats, assets, accounts, messages + from .resources import app, info, chats, assets, matrix, bridges, accounts, messages from .resources.info import InfoResource, AsyncInfoResource from .resources.assets import AssetsResource, AsyncAssetsResource + from .resources.app.app import AppResource, AsyncAppResource + from .resources.bridges import BridgesResource, AsyncBridgesResource from .resources.messages import MessagesResource, AsyncMessagesResource from .resources.chats.chats import ChatsResource, AsyncChatsResource + from .resources.matrix.matrix import MatrixResource, AsyncMatrixResource from .resources.accounts.accounts import AccountsResource, AsyncAccountsResource __all__ = [ @@ -142,6 +145,13 @@ def accounts(self) -> AccountsResource: return AccountsResource(self) + @cached_property + def bridges(self) -> BridgesResource: + """Manage bridge-backed account types and account availability""" + from .resources.bridges import BridgesResource + + return BridgesResource(self) + @cached_property def chats(self) -> ChatsResource: """Manage chats""" @@ -173,6 +183,20 @@ def info(self) -> InfoResource: return InfoResource(self) + @cached_property + def app(self) -> AppResource: + """Manage Beeper app login and encrypted messaging setup""" + from .resources.app import AppResource + + return AppResource(self) + + @cached_property + def matrix(self) -> MatrixResource: + """Matrix-compatible APIs for accounts, rooms, and connected network bridges.""" + from .resources.matrix import MatrixResource + + return MatrixResource(self) + @cached_property def with_raw_response(self) -> BeeperDesktopWithRawResponse: return BeeperDesktopWithRawResponse(self) @@ -454,6 +478,13 @@ def accounts(self) -> AsyncAccountsResource: return AsyncAccountsResource(self) + @cached_property + def bridges(self) -> AsyncBridgesResource: + """Manage bridge-backed account types and account availability""" + from .resources.bridges import AsyncBridgesResource + + return AsyncBridgesResource(self) + @cached_property def chats(self) -> AsyncChatsResource: """Manage chats""" @@ -485,6 +516,20 @@ def info(self) -> AsyncInfoResource: return AsyncInfoResource(self) + @cached_property + def app(self) -> AsyncAppResource: + """Manage Beeper app login and encrypted messaging setup""" + from .resources.app import AsyncAppResource + + return AsyncAppResource(self) + + @cached_property + def matrix(self) -> AsyncMatrixResource: + """Matrix-compatible APIs for accounts, rooms, and connected network bridges.""" + from .resources.matrix import AsyncMatrixResource + + return AsyncMatrixResource(self) + @cached_property def with_raw_response(self) -> AsyncBeeperDesktopWithRawResponse: return AsyncBeeperDesktopWithRawResponse(self) @@ -715,6 +760,13 @@ def accounts(self) -> accounts.AccountsResourceWithRawResponse: return AccountsResourceWithRawResponse(self._client.accounts) + @cached_property + def bridges(self) -> bridges.BridgesResourceWithRawResponse: + """Manage bridge-backed account types and account availability""" + from .resources.bridges import BridgesResourceWithRawResponse + + return BridgesResourceWithRawResponse(self._client.bridges) + @cached_property def chats(self) -> chats.ChatsResourceWithRawResponse: """Manage chats""" @@ -746,6 +798,20 @@ def info(self) -> info.InfoResourceWithRawResponse: return InfoResourceWithRawResponse(self._client.info) + @cached_property + def app(self) -> app.AppResourceWithRawResponse: + """Manage Beeper app login and encrypted messaging setup""" + from .resources.app import AppResourceWithRawResponse + + return AppResourceWithRawResponse(self._client.app) + + @cached_property + def matrix(self) -> matrix.MatrixResourceWithRawResponse: + """Matrix-compatible APIs for accounts, rooms, and connected network bridges.""" + from .resources.matrix import MatrixResourceWithRawResponse + + return MatrixResourceWithRawResponse(self._client.matrix) + class AsyncBeeperDesktopWithRawResponse: _client: AsyncBeeperDesktop @@ -767,6 +833,13 @@ def accounts(self) -> accounts.AsyncAccountsResourceWithRawResponse: return AsyncAccountsResourceWithRawResponse(self._client.accounts) + @cached_property + def bridges(self) -> bridges.AsyncBridgesResourceWithRawResponse: + """Manage bridge-backed account types and account availability""" + from .resources.bridges import AsyncBridgesResourceWithRawResponse + + return AsyncBridgesResourceWithRawResponse(self._client.bridges) + @cached_property def chats(self) -> chats.AsyncChatsResourceWithRawResponse: """Manage chats""" @@ -798,6 +871,20 @@ def info(self) -> info.AsyncInfoResourceWithRawResponse: return AsyncInfoResourceWithRawResponse(self._client.info) + @cached_property + def app(self) -> app.AsyncAppResourceWithRawResponse: + """Manage Beeper app login and encrypted messaging setup""" + from .resources.app import AsyncAppResourceWithRawResponse + + return AsyncAppResourceWithRawResponse(self._client.app) + + @cached_property + def matrix(self) -> matrix.AsyncMatrixResourceWithRawResponse: + """Matrix-compatible APIs for accounts, rooms, and connected network bridges.""" + from .resources.matrix import AsyncMatrixResourceWithRawResponse + + return AsyncMatrixResourceWithRawResponse(self._client.matrix) + class BeeperDesktopWithStreamedResponse: _client: BeeperDesktop @@ -819,6 +906,13 @@ def accounts(self) -> accounts.AccountsResourceWithStreamingResponse: return AccountsResourceWithStreamingResponse(self._client.accounts) + @cached_property + def bridges(self) -> bridges.BridgesResourceWithStreamingResponse: + """Manage bridge-backed account types and account availability""" + from .resources.bridges import BridgesResourceWithStreamingResponse + + return BridgesResourceWithStreamingResponse(self._client.bridges) + @cached_property def chats(self) -> chats.ChatsResourceWithStreamingResponse: """Manage chats""" @@ -850,6 +944,20 @@ def info(self) -> info.InfoResourceWithStreamingResponse: return InfoResourceWithStreamingResponse(self._client.info) + @cached_property + def app(self) -> app.AppResourceWithStreamingResponse: + """Manage Beeper app login and encrypted messaging setup""" + from .resources.app import AppResourceWithStreamingResponse + + return AppResourceWithStreamingResponse(self._client.app) + + @cached_property + def matrix(self) -> matrix.MatrixResourceWithStreamingResponse: + """Matrix-compatible APIs for accounts, rooms, and connected network bridges.""" + from .resources.matrix import MatrixResourceWithStreamingResponse + + return MatrixResourceWithStreamingResponse(self._client.matrix) + class AsyncBeeperDesktopWithStreamedResponse: _client: AsyncBeeperDesktop @@ -871,6 +979,13 @@ def accounts(self) -> accounts.AsyncAccountsResourceWithStreamingResponse: return AsyncAccountsResourceWithStreamingResponse(self._client.accounts) + @cached_property + def bridges(self) -> bridges.AsyncBridgesResourceWithStreamingResponse: + """Manage bridge-backed account types and account availability""" + from .resources.bridges import AsyncBridgesResourceWithStreamingResponse + + return AsyncBridgesResourceWithStreamingResponse(self._client.bridges) + @cached_property def chats(self) -> chats.AsyncChatsResourceWithStreamingResponse: """Manage chats""" @@ -902,6 +1017,20 @@ def info(self) -> info.AsyncInfoResourceWithStreamingResponse: return AsyncInfoResourceWithStreamingResponse(self._client.info) + @cached_property + def app(self) -> app.AsyncAppResourceWithStreamingResponse: + """Manage Beeper app login and encrypted messaging setup""" + from .resources.app import AsyncAppResourceWithStreamingResponse + + return AsyncAppResourceWithStreamingResponse(self._client.app) + + @cached_property + def matrix(self) -> matrix.AsyncMatrixResourceWithStreamingResponse: + """Matrix-compatible APIs for accounts, rooms, and connected network bridges.""" + from .resources.matrix import AsyncMatrixResourceWithStreamingResponse + + return AsyncMatrixResourceWithStreamingResponse(self._client.matrix) + Client = BeeperDesktop diff --git a/src/beeper_desktop_api/_files.py b/src/beeper_desktop_api/_files.py index 8a371d3..be8e0e1 100644 --- a/src/beeper_desktop_api/_files.py +++ b/src/beeper_desktop_api/_files.py @@ -99,7 +99,7 @@ async def async_to_httpx_files(files: RequestFiles | None) -> HttpxRequestFiles elif is_sequence_t(files): files = [(key, await _async_transform_file(file)) for key, file in files] else: - raise TypeError("Unexpected file type input {type(files)}, expected mapping or sequence") + raise TypeError(f"Unexpected file type input {type(files)}, expected mapping or sequence") return files diff --git a/src/beeper_desktop_api/_models.py b/src/beeper_desktop_api/_models.py index e22dd2a..69f41a6 100644 --- a/src/beeper_desktop_api/_models.py +++ b/src/beeper_desktop_api/_models.py @@ -25,7 +25,9 @@ ClassVar, Protocol, Required, + Annotated, ParamSpec, + TypeAlias, TypedDict, TypeGuard, final, @@ -79,7 +81,15 @@ from ._constants import RAW_RESPONSE_HEADER if TYPE_CHECKING: + from pydantic import GetCoreSchemaHandler, ValidatorFunctionWrapHandler + from pydantic_core import CoreSchema, core_schema from pydantic_core.core_schema import ModelField, ModelSchema, LiteralSchema, ModelFieldsSchema +else: + try: + from pydantic_core import CoreSchema, core_schema + except ImportError: + CoreSchema = None + core_schema = None __all__ = ["BaseModel", "GenericModel"] @@ -396,6 +406,76 @@ def model_dump_json( ) +class _EagerIterable(list[_T], Generic[_T]): + """ + Accepts any Iterable[T] input (including generators), consumes it + eagerly, and validates all items upfront. + + Validation preserves the original container type where possible + (e.g. a set[T] stays a set[T]). Serialization (model_dump / JSON) + always emits a list — round-tripping through model_dump() will not + restore the original container type. + """ + + @classmethod + def __get_pydantic_core_schema__( + cls, + source_type: Any, + handler: GetCoreSchemaHandler, + ) -> CoreSchema: + (item_type,) = get_args(source_type) or (Any,) + item_schema: CoreSchema = handler.generate_schema(item_type) + list_of_items_schema: CoreSchema = core_schema.list_schema(item_schema) + + return core_schema.no_info_wrap_validator_function( + cls._validate, + list_of_items_schema, + serialization=core_schema.plain_serializer_function_ser_schema( + cls._serialize, + info_arg=False, + ), + ) + + @staticmethod + def _validate(v: Iterable[_T], handler: "ValidatorFunctionWrapHandler") -> Any: + original_type: type[Any] = type(v) + + # Normalize to list so list_schema can validate each item + if isinstance(v, list): + items: list[_T] = v + else: + try: + items = list(v) + except TypeError as e: + raise TypeError("Value is not iterable") from e + + # Validate items against the inner schema + validated: list[_T] = handler(items) + + # Reconstruct original container type + if original_type is list: + return validated + # str(list) produces the list's repr, not a string built from items, + # so skip reconstruction for str and its subclasses. + if issubclass(original_type, str): + return validated + try: + return original_type(validated) + except (TypeError, ValueError): + # If the type cannot be reconstructed, just return the validated list + return validated + + @staticmethod + def _serialize(v: Iterable[_T]) -> list[_T]: + """Always serialize as a list so Pydantic's JSON encoder is happy.""" + if isinstance(v, list): + return v + return list(v) + + +EagerIterable: TypeAlias = Annotated[Iterable[_T], _EagerIterable] + + def _construct_field(value: object, field: FieldInfo, key: str) -> object: if value is None: return field_get_default(field) diff --git a/src/beeper_desktop_api/_version.py b/src/beeper_desktop_api/_version.py index 60fb169..701658d 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__ = "5.0.0" # x-release-please-version +__version__ = "5.1.0" # x-release-please-version diff --git a/src/beeper_desktop_api/resources/__init__.py b/src/beeper_desktop_api/resources/__init__.py index a066e9b..26dee5c 100644 --- a/src/beeper_desktop_api/resources/__init__.py +++ b/src/beeper_desktop_api/resources/__init__.py @@ -1,5 +1,13 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +from .app import ( + AppResource, + AsyncAppResource, + AppResourceWithRawResponse, + AsyncAppResourceWithRawResponse, + AppResourceWithStreamingResponse, + AsyncAppResourceWithStreamingResponse, +) from .info import ( InfoResource, AsyncInfoResource, @@ -24,6 +32,22 @@ AssetsResourceWithStreamingResponse, AsyncAssetsResourceWithStreamingResponse, ) +from .matrix import ( + MatrixResource, + AsyncMatrixResource, + MatrixResourceWithRawResponse, + AsyncMatrixResourceWithRawResponse, + MatrixResourceWithStreamingResponse, + AsyncMatrixResourceWithStreamingResponse, +) +from .bridges import ( + BridgesResource, + AsyncBridgesResource, + BridgesResourceWithRawResponse, + AsyncBridgesResourceWithRawResponse, + BridgesResourceWithStreamingResponse, + AsyncBridgesResourceWithStreamingResponse, +) from .accounts import ( AccountsResource, AsyncAccountsResource, @@ -48,6 +72,12 @@ "AsyncAccountsResourceWithRawResponse", "AccountsResourceWithStreamingResponse", "AsyncAccountsResourceWithStreamingResponse", + "BridgesResource", + "AsyncBridgesResource", + "BridgesResourceWithRawResponse", + "AsyncBridgesResourceWithRawResponse", + "BridgesResourceWithStreamingResponse", + "AsyncBridgesResourceWithStreamingResponse", "ChatsResource", "AsyncChatsResource", "ChatsResourceWithRawResponse", @@ -72,4 +102,16 @@ "AsyncInfoResourceWithRawResponse", "InfoResourceWithStreamingResponse", "AsyncInfoResourceWithStreamingResponse", + "AppResource", + "AsyncAppResource", + "AppResourceWithRawResponse", + "AsyncAppResourceWithRawResponse", + "AppResourceWithStreamingResponse", + "AsyncAppResourceWithStreamingResponse", + "MatrixResource", + "AsyncMatrixResource", + "MatrixResourceWithRawResponse", + "AsyncMatrixResourceWithRawResponse", + "MatrixResourceWithStreamingResponse", + "AsyncMatrixResourceWithStreamingResponse", ] diff --git a/src/beeper_desktop_api/resources/app/__init__.py b/src/beeper_desktop_api/resources/app/__init__.py new file mode 100644 index 0000000..a21f690 --- /dev/null +++ b/src/beeper_desktop_api/resources/app/__init__.py @@ -0,0 +1,47 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .app import ( + AppResource, + AsyncAppResource, + AppResourceWithRawResponse, + AsyncAppResourceWithRawResponse, + AppResourceWithStreamingResponse, + AsyncAppResourceWithStreamingResponse, +) +from .e2ee import ( + E2eeResource, + AsyncE2eeResource, + E2eeResourceWithRawResponse, + AsyncE2eeResourceWithRawResponse, + E2eeResourceWithStreamingResponse, + AsyncE2eeResourceWithStreamingResponse, +) +from .login import ( + LoginResource, + AsyncLoginResource, + LoginResourceWithRawResponse, + AsyncLoginResourceWithRawResponse, + LoginResourceWithStreamingResponse, + AsyncLoginResourceWithStreamingResponse, +) + +__all__ = [ + "LoginResource", + "AsyncLoginResource", + "LoginResourceWithRawResponse", + "AsyncLoginResourceWithRawResponse", + "LoginResourceWithStreamingResponse", + "AsyncLoginResourceWithStreamingResponse", + "E2eeResource", + "AsyncE2eeResource", + "E2eeResourceWithRawResponse", + "AsyncE2eeResourceWithRawResponse", + "E2eeResourceWithStreamingResponse", + "AsyncE2eeResourceWithStreamingResponse", + "AppResource", + "AsyncAppResource", + "AppResourceWithRawResponse", + "AsyncAppResourceWithRawResponse", + "AppResourceWithStreamingResponse", + "AsyncAppResourceWithStreamingResponse", +] diff --git a/src/beeper_desktop_api/resources/app/app.py b/src/beeper_desktop_api/resources/app/app.py new file mode 100644 index 0000000..73858b9 --- /dev/null +++ b/src/beeper_desktop_api/resources/app/app.py @@ -0,0 +1,223 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from .login import ( + LoginResource, + AsyncLoginResource, + LoginResourceWithRawResponse, + AsyncLoginResourceWithRawResponse, + LoginResourceWithStreamingResponse, + AsyncLoginResourceWithStreamingResponse, +) +from ..._types import Body, Query, Headers, NotGiven, not_given +from ..._compat import cached_property +from .e2ee.e2ee import ( + E2eeResource, + AsyncE2eeResource, + E2eeResourceWithRawResponse, + AsyncE2eeResourceWithRawResponse, + E2eeResourceWithStreamingResponse, + AsyncE2eeResourceWithStreamingResponse, +) +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 +from ...types.app_status_response import AppStatusResponse + +__all__ = ["AppResource", "AsyncAppResource"] + + +class AppResource(SyncAPIResource): + """Manage Beeper app login and encrypted messaging setup""" + + @cached_property + def login(self) -> LoginResource: + """Complete first-party Beeper app login""" + return LoginResource(self._client) + + @cached_property + def e2ee(self) -> E2eeResource: + """Manage encrypted messaging setup""" + return E2eeResource(self._client) + + @cached_property + def with_raw_response(self) -> AppResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AppResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AppResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AppResourceWithStreamingResponse(self) + + def status( + 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, + ) -> AppStatusResponse: + """ + Return the current Beeper Desktop sign-in and encrypted messaging setup state. + This endpoint is public before sign-in so apps can discover that login is + needed; after sign-in, pass a read token. + """ + return self._get( + "/v1/app/status", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AppStatusResponse, + ) + + +class AsyncAppResource(AsyncAPIResource): + """Manage Beeper app login and encrypted messaging setup""" + + @cached_property + def login(self) -> AsyncLoginResource: + """Complete first-party Beeper app login""" + return AsyncLoginResource(self._client) + + @cached_property + def e2ee(self) -> AsyncE2eeResource: + """Manage encrypted messaging setup""" + return AsyncE2eeResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncAppResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncAppResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncAppResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AsyncAppResourceWithStreamingResponse(self) + + async def status( + 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, + ) -> AppStatusResponse: + """ + Return the current Beeper Desktop sign-in and encrypted messaging setup state. + This endpoint is public before sign-in so apps can discover that login is + needed; after sign-in, pass a read token. + """ + return await self._get( + "/v1/app/status", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AppStatusResponse, + ) + + +class AppResourceWithRawResponse: + def __init__(self, app: AppResource) -> None: + self._app = app + + self.status = to_raw_response_wrapper( + app.status, + ) + + @cached_property + def login(self) -> LoginResourceWithRawResponse: + """Complete first-party Beeper app login""" + return LoginResourceWithRawResponse(self._app.login) + + @cached_property + def e2ee(self) -> E2eeResourceWithRawResponse: + """Manage encrypted messaging setup""" + return E2eeResourceWithRawResponse(self._app.e2ee) + + +class AsyncAppResourceWithRawResponse: + def __init__(self, app: AsyncAppResource) -> None: + self._app = app + + self.status = async_to_raw_response_wrapper( + app.status, + ) + + @cached_property + def login(self) -> AsyncLoginResourceWithRawResponse: + """Complete first-party Beeper app login""" + return AsyncLoginResourceWithRawResponse(self._app.login) + + @cached_property + def e2ee(self) -> AsyncE2eeResourceWithRawResponse: + """Manage encrypted messaging setup""" + return AsyncE2eeResourceWithRawResponse(self._app.e2ee) + + +class AppResourceWithStreamingResponse: + def __init__(self, app: AppResource) -> None: + self._app = app + + self.status = to_streamed_response_wrapper( + app.status, + ) + + @cached_property + def login(self) -> LoginResourceWithStreamingResponse: + """Complete first-party Beeper app login""" + return LoginResourceWithStreamingResponse(self._app.login) + + @cached_property + def e2ee(self) -> E2eeResourceWithStreamingResponse: + """Manage encrypted messaging setup""" + return E2eeResourceWithStreamingResponse(self._app.e2ee) + + +class AsyncAppResourceWithStreamingResponse: + def __init__(self, app: AsyncAppResource) -> None: + self._app = app + + self.status = async_to_streamed_response_wrapper( + app.status, + ) + + @cached_property + def login(self) -> AsyncLoginResourceWithStreamingResponse: + """Complete first-party Beeper app login""" + return AsyncLoginResourceWithStreamingResponse(self._app.login) + + @cached_property + def e2ee(self) -> AsyncE2eeResourceWithStreamingResponse: + """Manage encrypted messaging setup""" + return AsyncE2eeResourceWithStreamingResponse(self._app.e2ee) diff --git a/src/beeper_desktop_api/resources/app/e2ee/__init__.py b/src/beeper_desktop_api/resources/app/e2ee/__init__.py new file mode 100644 index 0000000..f7fa574 --- /dev/null +++ b/src/beeper_desktop_api/resources/app/e2ee/__init__.py @@ -0,0 +1,47 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .e2ee import ( + E2eeResource, + AsyncE2eeResource, + E2eeResourceWithRawResponse, + AsyncE2eeResourceWithRawResponse, + E2eeResourceWithStreamingResponse, + AsyncE2eeResourceWithStreamingResponse, +) +from .verification import ( + VerificationResource, + AsyncVerificationResource, + VerificationResourceWithRawResponse, + AsyncVerificationResourceWithRawResponse, + VerificationResourceWithStreamingResponse, + AsyncVerificationResourceWithStreamingResponse, +) +from .recovery_code import ( + RecoveryCodeResource, + AsyncRecoveryCodeResource, + RecoveryCodeResourceWithRawResponse, + AsyncRecoveryCodeResourceWithRawResponse, + RecoveryCodeResourceWithStreamingResponse, + AsyncRecoveryCodeResourceWithStreamingResponse, +) + +__all__ = [ + "RecoveryCodeResource", + "AsyncRecoveryCodeResource", + "RecoveryCodeResourceWithRawResponse", + "AsyncRecoveryCodeResourceWithRawResponse", + "RecoveryCodeResourceWithStreamingResponse", + "AsyncRecoveryCodeResourceWithStreamingResponse", + "VerificationResource", + "AsyncVerificationResource", + "VerificationResourceWithRawResponse", + "AsyncVerificationResourceWithRawResponse", + "VerificationResourceWithStreamingResponse", + "AsyncVerificationResourceWithStreamingResponse", + "E2eeResource", + "AsyncE2eeResource", + "E2eeResourceWithRawResponse", + "AsyncE2eeResourceWithRawResponse", + "E2eeResourceWithStreamingResponse", + "AsyncE2eeResourceWithStreamingResponse", +] diff --git a/src/beeper_desktop_api/resources/app/e2ee/e2ee.py b/src/beeper_desktop_api/resources/app/e2ee/e2ee.py new file mode 100644 index 0000000..285e853 --- /dev/null +++ b/src/beeper_desktop_api/resources/app/e2ee/e2ee.py @@ -0,0 +1,150 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from .verification.verification import ( + VerificationResource, + AsyncVerificationResource, + VerificationResourceWithRawResponse, + AsyncVerificationResourceWithRawResponse, + VerificationResourceWithStreamingResponse, + AsyncVerificationResourceWithStreamingResponse, +) +from .recovery_code.recovery_code import ( + RecoveryCodeResource, + AsyncRecoveryCodeResource, + RecoveryCodeResourceWithRawResponse, + AsyncRecoveryCodeResourceWithRawResponse, + RecoveryCodeResourceWithStreamingResponse, + AsyncRecoveryCodeResourceWithStreamingResponse, +) + +__all__ = ["E2eeResource", "AsyncE2eeResource"] + + +class E2eeResource(SyncAPIResource): + """Manage encrypted messaging setup""" + + @cached_property + def recovery_code(self) -> RecoveryCodeResource: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return RecoveryCodeResource(self._client) + + @cached_property + def verification(self) -> VerificationResource: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return VerificationResource(self._client) + + @cached_property + def with_raw_response(self) -> E2eeResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return E2eeResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> E2eeResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return E2eeResourceWithStreamingResponse(self) + + +class AsyncE2eeResource(AsyncAPIResource): + """Manage encrypted messaging setup""" + + @cached_property + def recovery_code(self) -> AsyncRecoveryCodeResource: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return AsyncRecoveryCodeResource(self._client) + + @cached_property + def verification(self) -> AsyncVerificationResource: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return AsyncVerificationResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncE2eeResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncE2eeResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncE2eeResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AsyncE2eeResourceWithStreamingResponse(self) + + +class E2eeResourceWithRawResponse: + def __init__(self, e2ee: E2eeResource) -> None: + self._e2ee = e2ee + + @cached_property + def recovery_code(self) -> RecoveryCodeResourceWithRawResponse: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return RecoveryCodeResourceWithRawResponse(self._e2ee.recovery_code) + + @cached_property + def verification(self) -> VerificationResourceWithRawResponse: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return VerificationResourceWithRawResponse(self._e2ee.verification) + + +class AsyncE2eeResourceWithRawResponse: + def __init__(self, e2ee: AsyncE2eeResource) -> None: + self._e2ee = e2ee + + @cached_property + def recovery_code(self) -> AsyncRecoveryCodeResourceWithRawResponse: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return AsyncRecoveryCodeResourceWithRawResponse(self._e2ee.recovery_code) + + @cached_property + def verification(self) -> AsyncVerificationResourceWithRawResponse: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return AsyncVerificationResourceWithRawResponse(self._e2ee.verification) + + +class E2eeResourceWithStreamingResponse: + def __init__(self, e2ee: E2eeResource) -> None: + self._e2ee = e2ee + + @cached_property + def recovery_code(self) -> RecoveryCodeResourceWithStreamingResponse: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return RecoveryCodeResourceWithStreamingResponse(self._e2ee.recovery_code) + + @cached_property + def verification(self) -> VerificationResourceWithStreamingResponse: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return VerificationResourceWithStreamingResponse(self._e2ee.verification) + + +class AsyncE2eeResourceWithStreamingResponse: + def __init__(self, e2ee: AsyncE2eeResource) -> None: + self._e2ee = e2ee + + @cached_property + def recovery_code(self) -> AsyncRecoveryCodeResourceWithStreamingResponse: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return AsyncRecoveryCodeResourceWithStreamingResponse(self._e2ee.recovery_code) + + @cached_property + def verification(self) -> AsyncVerificationResourceWithStreamingResponse: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return AsyncVerificationResourceWithStreamingResponse(self._e2ee.verification) diff --git a/src/beeper_desktop_api/resources/app/e2ee/recovery_code/__init__.py b/src/beeper_desktop_api/resources/app/e2ee/recovery_code/__init__.py new file mode 100644 index 0000000..f60d377 --- /dev/null +++ b/src/beeper_desktop_api/resources/app/e2ee/recovery_code/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .reset import ( + ResetResource, + AsyncResetResource, + ResetResourceWithRawResponse, + AsyncResetResourceWithRawResponse, + ResetResourceWithStreamingResponse, + AsyncResetResourceWithStreamingResponse, +) +from .recovery_code import ( + RecoveryCodeResource, + AsyncRecoveryCodeResource, + RecoveryCodeResourceWithRawResponse, + AsyncRecoveryCodeResourceWithRawResponse, + RecoveryCodeResourceWithStreamingResponse, + AsyncRecoveryCodeResourceWithStreamingResponse, +) + +__all__ = [ + "ResetResource", + "AsyncResetResource", + "ResetResourceWithRawResponse", + "AsyncResetResourceWithRawResponse", + "ResetResourceWithStreamingResponse", + "AsyncResetResourceWithStreamingResponse", + "RecoveryCodeResource", + "AsyncRecoveryCodeResource", + "RecoveryCodeResourceWithRawResponse", + "AsyncRecoveryCodeResourceWithRawResponse", + "RecoveryCodeResourceWithStreamingResponse", + "AsyncRecoveryCodeResourceWithStreamingResponse", +] diff --git a/src/beeper_desktop_api/resources/app/e2ee/recovery_code/recovery_code.py b/src/beeper_desktop_api/resources/app/e2ee/recovery_code/recovery_code.py new file mode 100644 index 0000000..47a7804 --- /dev/null +++ b/src/beeper_desktop_api/resources/app/e2ee/recovery_code/recovery_code.py @@ -0,0 +1,264 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from .reset import ( + ResetResource, + AsyncResetResource, + ResetResourceWithRawResponse, + AsyncResetResourceWithRawResponse, + ResetResourceWithStreamingResponse, + AsyncResetResourceWithStreamingResponse, +) +from ....._types import Body, Query, Headers, NotGiven, not_given +from ....._utils import maybe_transform, async_maybe_transform +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 +from .....types.app.e2ee import recovery_code_verify_params +from .....types.app.e2ee.recovery_code_verify_response import RecoveryCodeVerifyResponse +from .....types.app.e2ee.recovery_code_mark_backed_up_response import RecoveryCodeMarkBackedUpResponse + +__all__ = ["RecoveryCodeResource", "AsyncRecoveryCodeResource"] + + +class RecoveryCodeResource(SyncAPIResource): + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + + @cached_property + def reset(self) -> ResetResource: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return ResetResource(self._client) + + @cached_property + def with_raw_response(self) -> RecoveryCodeResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return RecoveryCodeResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> RecoveryCodeResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return RecoveryCodeResourceWithStreamingResponse(self) + + def mark_backed_up( + 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, + ) -> RecoveryCodeMarkBackedUpResponse: + """Record that the user saved their recovery key.""" + return self._post( + "/v1/app/e2ee/recovery-code/mark-backed-up", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=RecoveryCodeMarkBackedUpResponse, + ) + + def verify( + self, + *, + recovery_code: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RecoveryCodeVerifyResponse: + """ + Unlock encrypted messages with the user recovery key. + + Args: + recovery_code: Recovery key saved by the user. + + 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 + """ + return self._post( + "/v1/app/e2ee/recovery-code/verify", + body=maybe_transform( + {"recovery_code": recovery_code}, recovery_code_verify_params.RecoveryCodeVerifyParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=RecoveryCodeVerifyResponse, + ) + + +class AsyncRecoveryCodeResource(AsyncAPIResource): + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + + @cached_property + def reset(self) -> AsyncResetResource: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return AsyncResetResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncRecoveryCodeResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncRecoveryCodeResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncRecoveryCodeResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AsyncRecoveryCodeResourceWithStreamingResponse(self) + + async def mark_backed_up( + 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, + ) -> RecoveryCodeMarkBackedUpResponse: + """Record that the user saved their recovery key.""" + return await self._post( + "/v1/app/e2ee/recovery-code/mark-backed-up", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=RecoveryCodeMarkBackedUpResponse, + ) + + async def verify( + self, + *, + recovery_code: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RecoveryCodeVerifyResponse: + """ + Unlock encrypted messages with the user recovery key. + + Args: + recovery_code: Recovery key saved by the user. + + 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 + """ + return await self._post( + "/v1/app/e2ee/recovery-code/verify", + body=await async_maybe_transform( + {"recovery_code": recovery_code}, recovery_code_verify_params.RecoveryCodeVerifyParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=RecoveryCodeVerifyResponse, + ) + + +class RecoveryCodeResourceWithRawResponse: + def __init__(self, recovery_code: RecoveryCodeResource) -> None: + self._recovery_code = recovery_code + + self.mark_backed_up = to_raw_response_wrapper( + recovery_code.mark_backed_up, + ) + self.verify = to_raw_response_wrapper( + recovery_code.verify, + ) + + @cached_property + def reset(self) -> ResetResourceWithRawResponse: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return ResetResourceWithRawResponse(self._recovery_code.reset) + + +class AsyncRecoveryCodeResourceWithRawResponse: + def __init__(self, recovery_code: AsyncRecoveryCodeResource) -> None: + self._recovery_code = recovery_code + + self.mark_backed_up = async_to_raw_response_wrapper( + recovery_code.mark_backed_up, + ) + self.verify = async_to_raw_response_wrapper( + recovery_code.verify, + ) + + @cached_property + def reset(self) -> AsyncResetResourceWithRawResponse: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return AsyncResetResourceWithRawResponse(self._recovery_code.reset) + + +class RecoveryCodeResourceWithStreamingResponse: + def __init__(self, recovery_code: RecoveryCodeResource) -> None: + self._recovery_code = recovery_code + + self.mark_backed_up = to_streamed_response_wrapper( + recovery_code.mark_backed_up, + ) + self.verify = to_streamed_response_wrapper( + recovery_code.verify, + ) + + @cached_property + def reset(self) -> ResetResourceWithStreamingResponse: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return ResetResourceWithStreamingResponse(self._recovery_code.reset) + + +class AsyncRecoveryCodeResourceWithStreamingResponse: + def __init__(self, recovery_code: AsyncRecoveryCodeResource) -> None: + self._recovery_code = recovery_code + + self.mark_backed_up = async_to_streamed_response_wrapper( + recovery_code.mark_backed_up, + ) + self.verify = async_to_streamed_response_wrapper( + recovery_code.verify, + ) + + @cached_property + def reset(self) -> AsyncResetResourceWithStreamingResponse: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return AsyncResetResourceWithStreamingResponse(self._recovery_code.reset) diff --git a/src/beeper_desktop_api/resources/app/e2ee/recovery_code/reset.py b/src/beeper_desktop_api/resources/app/e2ee/recovery_code/reset.py new file mode 100644 index 0000000..63a7fa0 --- /dev/null +++ b/src/beeper_desktop_api/resources/app/e2ee/recovery_code/reset.py @@ -0,0 +1,252 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ....._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ....._utils import maybe_transform, async_maybe_transform +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 +from .....types.app.e2ee.recovery_code import reset_create_params, reset_confirm_params +from .....types.app.e2ee.recovery_code.reset_create_response import ResetCreateResponse +from .....types.app.e2ee.recovery_code.reset_confirm_response import ResetConfirmResponse + +__all__ = ["ResetResource", "AsyncResetResource"] + + +class ResetResource(SyncAPIResource): + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + + @cached_property + def with_raw_response(self) -> ResetResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return ResetResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> ResetResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return ResetResourceWithStreamingResponse(self) + + def create( + self, + *, + recovery_code: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> ResetCreateResponse: + """ + Create a new recovery key when the user cannot use the existing one. + + Args: + recovery_code: Existing recovery key, if the user has it. + + 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 + """ + return self._post( + "/v1/app/e2ee/recovery-code/reset", + body=maybe_transform({"recovery_code": recovery_code}, reset_create_params.ResetCreateParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ResetCreateResponse, + ) + + def confirm( + self, + *, + recovery_code: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> ResetConfirmResponse: + """ + Confirm that the new recovery key should be used for this account. + + Args: + recovery_code: New recovery key returned by the reset step. + + 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 + """ + return self._post( + "/v1/app/e2ee/recovery-code/reset/confirm", + body=maybe_transform({"recovery_code": recovery_code}, reset_confirm_params.ResetConfirmParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ResetConfirmResponse, + ) + + +class AsyncResetResource(AsyncAPIResource): + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + + @cached_property + def with_raw_response(self) -> AsyncResetResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncResetResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncResetResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AsyncResetResourceWithStreamingResponse(self) + + async def create( + self, + *, + recovery_code: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> ResetCreateResponse: + """ + Create a new recovery key when the user cannot use the existing one. + + Args: + recovery_code: Existing recovery key, if the user has it. + + 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 + """ + return await self._post( + "/v1/app/e2ee/recovery-code/reset", + body=await async_maybe_transform({"recovery_code": recovery_code}, reset_create_params.ResetCreateParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ResetCreateResponse, + ) + + async def confirm( + self, + *, + recovery_code: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> ResetConfirmResponse: + """ + Confirm that the new recovery key should be used for this account. + + Args: + recovery_code: New recovery key returned by the reset step. + + 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 + """ + return await self._post( + "/v1/app/e2ee/recovery-code/reset/confirm", + body=await async_maybe_transform({"recovery_code": recovery_code}, reset_confirm_params.ResetConfirmParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ResetConfirmResponse, + ) + + +class ResetResourceWithRawResponse: + def __init__(self, reset: ResetResource) -> None: + self._reset = reset + + self.create = to_raw_response_wrapper( + reset.create, + ) + self.confirm = to_raw_response_wrapper( + reset.confirm, + ) + + +class AsyncResetResourceWithRawResponse: + def __init__(self, reset: AsyncResetResource) -> None: + self._reset = reset + + self.create = async_to_raw_response_wrapper( + reset.create, + ) + self.confirm = async_to_raw_response_wrapper( + reset.confirm, + ) + + +class ResetResourceWithStreamingResponse: + def __init__(self, reset: ResetResource) -> None: + self._reset = reset + + self.create = to_streamed_response_wrapper( + reset.create, + ) + self.confirm = to_streamed_response_wrapper( + reset.confirm, + ) + + +class AsyncResetResourceWithStreamingResponse: + def __init__(self, reset: AsyncResetResource) -> None: + self._reset = reset + + self.create = async_to_streamed_response_wrapper( + reset.create, + ) + self.confirm = async_to_streamed_response_wrapper( + reset.confirm, + ) diff --git a/src/beeper_desktop_api/resources/app/e2ee/verification/__init__.py b/src/beeper_desktop_api/resources/app/e2ee/verification/__init__.py new file mode 100644 index 0000000..920dcd8 --- /dev/null +++ b/src/beeper_desktop_api/resources/app/e2ee/verification/__init__.py @@ -0,0 +1,47 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .qr import ( + QrResource, + AsyncQrResource, + QrResourceWithRawResponse, + AsyncQrResourceWithRawResponse, + QrResourceWithStreamingResponse, + AsyncQrResourceWithStreamingResponse, +) +from .sas import ( + SasResource, + AsyncSasResource, + SasResourceWithRawResponse, + AsyncSasResourceWithRawResponse, + SasResourceWithStreamingResponse, + AsyncSasResourceWithStreamingResponse, +) +from .verification import ( + VerificationResource, + AsyncVerificationResource, + VerificationResourceWithRawResponse, + AsyncVerificationResourceWithRawResponse, + VerificationResourceWithStreamingResponse, + AsyncVerificationResourceWithStreamingResponse, +) + +__all__ = [ + "QrResource", + "AsyncQrResource", + "QrResourceWithRawResponse", + "AsyncQrResourceWithRawResponse", + "QrResourceWithStreamingResponse", + "AsyncQrResourceWithStreamingResponse", + "SasResource", + "AsyncSasResource", + "SasResourceWithRawResponse", + "AsyncSasResourceWithRawResponse", + "SasResourceWithStreamingResponse", + "AsyncSasResourceWithStreamingResponse", + "VerificationResource", + "AsyncVerificationResource", + "VerificationResourceWithRawResponse", + "AsyncVerificationResourceWithRawResponse", + "VerificationResourceWithStreamingResponse", + "AsyncVerificationResourceWithStreamingResponse", +] diff --git a/src/beeper_desktop_api/resources/app/e2ee/verification/qr.py b/src/beeper_desktop_api/resources/app/e2ee/verification/qr.py new file mode 100644 index 0000000..a501c23 --- /dev/null +++ b/src/beeper_desktop_api/resources/app/e2ee/verification/qr.py @@ -0,0 +1,258 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ....._types import Body, Query, Headers, NotGiven, not_given +from ....._utils import path_template, maybe_transform, async_maybe_transform +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 +from .....types.app.e2ee.verification import qr_scan_params +from .....types.app.e2ee.verification.qr_scan_response import QrScanResponse +from .....types.app.e2ee.verification.qr_confirm_scanned_response import QrConfirmScannedResponse + +__all__ = ["QrResource", "AsyncQrResource"] + + +class QrResource(SyncAPIResource): + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + + @cached_property + def with_raw_response(self) -> QrResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return QrResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> QrResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return QrResourceWithStreamingResponse(self) + + def confirm_scanned( + self, + verification_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> QrConfirmScannedResponse: + """ + Confirm that another device scanned this device QR code. + + Args: + verification_id: Verification ID. + + 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 + """ + if not verification_id: + raise ValueError(f"Expected a non-empty value for `verification_id` but received {verification_id!r}") + return self._post( + path_template( + "/v1/app/e2ee/verification/{verification_id}/qr/confirm-scanned", verification_id=verification_id + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=QrConfirmScannedResponse, + ) + + def scan( + self, + *, + data: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> QrScanResponse: + """ + Submit the QR code scanned from another signed-in device. + + Args: + data: QR code payload scanned from the other device. + + 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 + """ + return self._post( + "/v1/app/e2ee/verification/qr/scan", + body=maybe_transform({"data": data}, qr_scan_params.QrScanParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=QrScanResponse, + ) + + +class AsyncQrResource(AsyncAPIResource): + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + + @cached_property + def with_raw_response(self) -> AsyncQrResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncQrResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncQrResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AsyncQrResourceWithStreamingResponse(self) + + async def confirm_scanned( + self, + verification_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> QrConfirmScannedResponse: + """ + Confirm that another device scanned this device QR code. + + Args: + verification_id: Verification ID. + + 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 + """ + if not verification_id: + raise ValueError(f"Expected a non-empty value for `verification_id` but received {verification_id!r}") + return await self._post( + path_template( + "/v1/app/e2ee/verification/{verification_id}/qr/confirm-scanned", verification_id=verification_id + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=QrConfirmScannedResponse, + ) + + async def scan( + self, + *, + data: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> QrScanResponse: + """ + Submit the QR code scanned from another signed-in device. + + Args: + data: QR code payload scanned from the other device. + + 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 + """ + return await self._post( + "/v1/app/e2ee/verification/qr/scan", + body=await async_maybe_transform({"data": data}, qr_scan_params.QrScanParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=QrScanResponse, + ) + + +class QrResourceWithRawResponse: + def __init__(self, qr: QrResource) -> None: + self._qr = qr + + self.confirm_scanned = to_raw_response_wrapper( + qr.confirm_scanned, + ) + self.scan = to_raw_response_wrapper( + qr.scan, + ) + + +class AsyncQrResourceWithRawResponse: + def __init__(self, qr: AsyncQrResource) -> None: + self._qr = qr + + self.confirm_scanned = async_to_raw_response_wrapper( + qr.confirm_scanned, + ) + self.scan = async_to_raw_response_wrapper( + qr.scan, + ) + + +class QrResourceWithStreamingResponse: + def __init__(self, qr: QrResource) -> None: + self._qr = qr + + self.confirm_scanned = to_streamed_response_wrapper( + qr.confirm_scanned, + ) + self.scan = to_streamed_response_wrapper( + qr.scan, + ) + + +class AsyncQrResourceWithStreamingResponse: + def __init__(self, qr: AsyncQrResource) -> None: + self._qr = qr + + self.confirm_scanned = async_to_streamed_response_wrapper( + qr.confirm_scanned, + ) + self.scan = async_to_streamed_response_wrapper( + qr.scan, + ) diff --git a/src/beeper_desktop_api/resources/app/e2ee/verification/sas.py b/src/beeper_desktop_api/resources/app/e2ee/verification/sas.py new file mode 100644 index 0000000..f72cd16 --- /dev/null +++ b/src/beeper_desktop_api/resources/app/e2ee/verification/sas.py @@ -0,0 +1,255 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ....._types import Body, Query, Headers, NotGiven, not_given +from ....._utils import path_template +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 +from .....types.app.e2ee.verification.sa_start_response import SaStartResponse +from .....types.app.e2ee.verification.sa_confirm_response import SaConfirmResponse + +__all__ = ["SasResource", "AsyncSasResource"] + + +class SasResource(SyncAPIResource): + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + + @cached_property + def with_raw_response(self) -> SasResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return SasResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> SasResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return SasResourceWithStreamingResponse(self) + + def confirm( + self, + verification_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SaConfirmResponse: + """ + Confirm that the emoji or number sequence matches on both devices. + + Args: + verification_id: Verification ID. + + 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 + """ + if not verification_id: + raise ValueError(f"Expected a non-empty value for `verification_id` but received {verification_id!r}") + return self._post( + path_template("/v1/app/e2ee/verification/{verification_id}/sas/confirm", verification_id=verification_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SaConfirmResponse, + ) + + def start( + self, + verification_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SaStartResponse: + """ + Start emoji comparison for device verification. + + Args: + verification_id: Verification ID. + + 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 + """ + if not verification_id: + raise ValueError(f"Expected a non-empty value for `verification_id` but received {verification_id!r}") + return self._post( + path_template("/v1/app/e2ee/verification/{verification_id}/sas/start", verification_id=verification_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SaStartResponse, + ) + + +class AsyncSasResource(AsyncAPIResource): + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + + @cached_property + def with_raw_response(self) -> AsyncSasResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncSasResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncSasResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AsyncSasResourceWithStreamingResponse(self) + + async def confirm( + self, + verification_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SaConfirmResponse: + """ + Confirm that the emoji or number sequence matches on both devices. + + Args: + verification_id: Verification ID. + + 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 + """ + if not verification_id: + raise ValueError(f"Expected a non-empty value for `verification_id` but received {verification_id!r}") + return await self._post( + path_template("/v1/app/e2ee/verification/{verification_id}/sas/confirm", verification_id=verification_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SaConfirmResponse, + ) + + async def start( + self, + verification_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SaStartResponse: + """ + Start emoji comparison for device verification. + + Args: + verification_id: Verification ID. + + 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 + """ + if not verification_id: + raise ValueError(f"Expected a non-empty value for `verification_id` but received {verification_id!r}") + return await self._post( + path_template("/v1/app/e2ee/verification/{verification_id}/sas/start", verification_id=verification_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SaStartResponse, + ) + + +class SasResourceWithRawResponse: + def __init__(self, sas: SasResource) -> None: + self._sas = sas + + self.confirm = to_raw_response_wrapper( + sas.confirm, + ) + self.start = to_raw_response_wrapper( + sas.start, + ) + + +class AsyncSasResourceWithRawResponse: + def __init__(self, sas: AsyncSasResource) -> None: + self._sas = sas + + self.confirm = async_to_raw_response_wrapper( + sas.confirm, + ) + self.start = async_to_raw_response_wrapper( + sas.start, + ) + + +class SasResourceWithStreamingResponse: + def __init__(self, sas: SasResource) -> None: + self._sas = sas + + self.confirm = to_streamed_response_wrapper( + sas.confirm, + ) + self.start = to_streamed_response_wrapper( + sas.start, + ) + + +class AsyncSasResourceWithStreamingResponse: + def __init__(self, sas: AsyncSasResource) -> None: + self._sas = sas + + self.confirm = async_to_streamed_response_wrapper( + sas.confirm, + ) + self.start = async_to_streamed_response_wrapper( + sas.start, + ) diff --git a/src/beeper_desktop_api/resources/app/e2ee/verification/verification.py b/src/beeper_desktop_api/resources/app/e2ee/verification/verification.py new file mode 100644 index 0000000..589e07f --- /dev/null +++ b/src/beeper_desktop_api/resources/app/e2ee/verification/verification.py @@ -0,0 +1,439 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from .qr import ( + QrResource, + AsyncQrResource, + QrResourceWithRawResponse, + AsyncQrResourceWithRawResponse, + QrResourceWithStreamingResponse, + AsyncQrResourceWithStreamingResponse, +) +from .sas import ( + SasResource, + AsyncSasResource, + SasResourceWithRawResponse, + AsyncSasResourceWithRawResponse, + SasResourceWithStreamingResponse, + AsyncSasResourceWithStreamingResponse, +) +from ....._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ....._utils import path_template, maybe_transform, async_maybe_transform +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 +from .....types.app.e2ee import verification_cancel_params, verification_create_params +from .....types.app.e2ee.verification_accept_response import VerificationAcceptResponse +from .....types.app.e2ee.verification_cancel_response import VerificationCancelResponse +from .....types.app.e2ee.verification_create_response import VerificationCreateResponse + +__all__ = ["VerificationResource", "AsyncVerificationResource"] + + +class VerificationResource(SyncAPIResource): + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + + @cached_property + def qr(self) -> QrResource: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return QrResource(self._client) + + @cached_property + def sas(self) -> SasResource: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return SasResource(self._client) + + @cached_property + def with_raw_response(self) -> VerificationResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return VerificationResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> VerificationResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return VerificationResourceWithStreamingResponse(self) + + def create( + self, + *, + user_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> VerificationCreateResponse: + """ + Start verifying this device from another signed-in device. + + Args: + user_id: User ID to verify. Defaults to the signed-in user. + + 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 + """ + return self._post( + "/v1/app/e2ee/verification", + body=maybe_transform({"user_id": user_id}, verification_create_params.VerificationCreateParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=VerificationCreateResponse, + ) + + def accept( + self, + verification_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> VerificationAcceptResponse: + """ + Accept an incoming device verification request. + + Args: + verification_id: Verification ID. + + 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 + """ + if not verification_id: + raise ValueError(f"Expected a non-empty value for `verification_id` but received {verification_id!r}") + return self._post( + path_template("/v1/app/e2ee/verification/{verification_id}/accept", verification_id=verification_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=VerificationAcceptResponse, + ) + + def cancel( + self, + verification_id: str, + *, + code: str | Omit = omit, + reason: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> VerificationCancelResponse: + """ + Cancel an active device verification request. + + Args: + verification_id: Verification ID. + + code: Optional cancellation code. + + reason: Optional user-facing cancellation reason. + + 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 + """ + if not verification_id: + raise ValueError(f"Expected a non-empty value for `verification_id` but received {verification_id!r}") + return self._post( + path_template("/v1/app/e2ee/verification/{verification_id}/cancel", verification_id=verification_id), + body=maybe_transform( + { + "code": code, + "reason": reason, + }, + verification_cancel_params.VerificationCancelParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=VerificationCancelResponse, + ) + + +class AsyncVerificationResource(AsyncAPIResource): + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + + @cached_property + def qr(self) -> AsyncQrResource: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return AsyncQrResource(self._client) + + @cached_property + def sas(self) -> AsyncSasResource: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return AsyncSasResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncVerificationResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncVerificationResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncVerificationResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AsyncVerificationResourceWithStreamingResponse(self) + + async def create( + self, + *, + user_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> VerificationCreateResponse: + """ + Start verifying this device from another signed-in device. + + Args: + user_id: User ID to verify. Defaults to the signed-in user. + + 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 + """ + return await self._post( + "/v1/app/e2ee/verification", + body=await async_maybe_transform({"user_id": user_id}, verification_create_params.VerificationCreateParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=VerificationCreateResponse, + ) + + async def accept( + self, + verification_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> VerificationAcceptResponse: + """ + Accept an incoming device verification request. + + Args: + verification_id: Verification ID. + + 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 + """ + if not verification_id: + raise ValueError(f"Expected a non-empty value for `verification_id` but received {verification_id!r}") + return await self._post( + path_template("/v1/app/e2ee/verification/{verification_id}/accept", verification_id=verification_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=VerificationAcceptResponse, + ) + + async def cancel( + self, + verification_id: str, + *, + code: str | Omit = omit, + reason: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> VerificationCancelResponse: + """ + Cancel an active device verification request. + + Args: + verification_id: Verification ID. + + code: Optional cancellation code. + + reason: Optional user-facing cancellation reason. + + 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 + """ + if not verification_id: + raise ValueError(f"Expected a non-empty value for `verification_id` but received {verification_id!r}") + return await self._post( + path_template("/v1/app/e2ee/verification/{verification_id}/cancel", verification_id=verification_id), + body=await async_maybe_transform( + { + "code": code, + "reason": reason, + }, + verification_cancel_params.VerificationCancelParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=VerificationCancelResponse, + ) + + +class VerificationResourceWithRawResponse: + def __init__(self, verification: VerificationResource) -> None: + self._verification = verification + + self.create = to_raw_response_wrapper( + verification.create, + ) + self.accept = to_raw_response_wrapper( + verification.accept, + ) + self.cancel = to_raw_response_wrapper( + verification.cancel, + ) + + @cached_property + def qr(self) -> QrResourceWithRawResponse: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return QrResourceWithRawResponse(self._verification.qr) + + @cached_property + def sas(self) -> SasResourceWithRawResponse: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return SasResourceWithRawResponse(self._verification.sas) + + +class AsyncVerificationResourceWithRawResponse: + def __init__(self, verification: AsyncVerificationResource) -> None: + self._verification = verification + + self.create = async_to_raw_response_wrapper( + verification.create, + ) + self.accept = async_to_raw_response_wrapper( + verification.accept, + ) + self.cancel = async_to_raw_response_wrapper( + verification.cancel, + ) + + @cached_property + def qr(self) -> AsyncQrResourceWithRawResponse: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return AsyncQrResourceWithRawResponse(self._verification.qr) + + @cached_property + def sas(self) -> AsyncSasResourceWithRawResponse: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return AsyncSasResourceWithRawResponse(self._verification.sas) + + +class VerificationResourceWithStreamingResponse: + def __init__(self, verification: VerificationResource) -> None: + self._verification = verification + + self.create = to_streamed_response_wrapper( + verification.create, + ) + self.accept = to_streamed_response_wrapper( + verification.accept, + ) + self.cancel = to_streamed_response_wrapper( + verification.cancel, + ) + + @cached_property + def qr(self) -> QrResourceWithStreamingResponse: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return QrResourceWithStreamingResponse(self._verification.qr) + + @cached_property + def sas(self) -> SasResourceWithStreamingResponse: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return SasResourceWithStreamingResponse(self._verification.sas) + + +class AsyncVerificationResourceWithStreamingResponse: + def __init__(self, verification: AsyncVerificationResource) -> None: + self._verification = verification + + self.create = async_to_streamed_response_wrapper( + verification.create, + ) + self.accept = async_to_streamed_response_wrapper( + verification.accept, + ) + self.cancel = async_to_streamed_response_wrapper( + verification.cancel, + ) + + @cached_property + def qr(self) -> AsyncQrResourceWithStreamingResponse: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return AsyncQrResourceWithStreamingResponse(self._verification.qr) + + @cached_property + def sas(self) -> AsyncSasResourceWithStreamingResponse: + """First-party sign-in and encrypted messaging setup for Beeper Desktop.""" + return AsyncSasResourceWithStreamingResponse(self._verification.sas) diff --git a/src/beeper_desktop_api/resources/app/login.py b/src/beeper_desktop_api/resources/app/login.py new file mode 100644 index 0000000..e67ff28 --- /dev/null +++ b/src/beeper_desktop_api/resources/app/login.py @@ -0,0 +1,508 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Any, cast +from typing_extensions import Literal + +import httpx + +from ..._types import Body, Query, Headers, NotGiven, not_given +from ..._utils import maybe_transform, async_maybe_transform +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 ...types.app import login_email_params, login_register_params, login_response_params +from ..._base_client import make_request_options +from ...types.app.login_start_response import LoginStartResponse +from ...types.app.login_register_response import LoginRegisterResponse +from ...types.app.login_response_response import LoginResponseResponse + +__all__ = ["LoginResource", "AsyncLoginResource"] + + +class LoginResource(SyncAPIResource): + """Complete first-party Beeper app login""" + + @cached_property + def with_raw_response(self) -> LoginResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return LoginResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> LoginResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return LoginResourceWithStreamingResponse(self) + + def email( + self, + *, + email: str, + request: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """ + Send a sign-in code to the user email address. + + Args: + email: Email address to send the sign-in code to. + + request: Login request ID returned by the start step. + + 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 + """ + return self._post( + "/v1/app/login/email", + body=maybe_transform( + { + "email": email, + "request": request, + }, + login_email_params.LoginEmailParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + security={}, + ), + cast_to=object, + ) + + def register( + self, + *, + accept_terms: Literal[True], + lead_token: str, + request: str, + username: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> LoginRegisterResponse: + """ + Create a Beeper account after the user chooses a username and accepts the Terms + of Use. + + Args: + accept_terms: Confirms that the user accepted the Terms of Use and acknowledged the Privacy + Policy. + + lead_token: Registration token returned by Beeper. + + request: Login request ID returned by the start step. + + username: Username selected by the user. + + 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 + """ + return self._post( + "/v1/app/login/register", + body=maybe_transform( + { + "accept_terms": accept_terms, + "lead_token": lead_token, + "request": request, + "username": username, + }, + login_register_params.LoginRegisterParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + security={}, + ), + cast_to=LoginRegisterResponse, + ) + + def response( + self, + *, + request: str, + response: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> LoginResponseResponse: + """Finish sign-in with the code sent to the user email address. + + If the user needs a + new account, the response includes account creation copy and username + suggestions. + + Args: + request: Login request ID returned by the start step. + + response: Sign-in code from the user email. + + 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 + """ + return cast( + LoginResponseResponse, + self._post( + "/v1/app/login/response", + body=maybe_transform( + { + "request": request, + "response": response, + }, + login_response_params.LoginResponseParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + security={}, + ), + cast_to=cast( + Any, LoginResponseResponse + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + def start( + 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, + ) -> LoginStartResponse: + """Start a first-party Beeper Desktop sign-in session.""" + return self._post( + "/v1/app/login/start", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + security={}, + ), + cast_to=LoginStartResponse, + ) + + +class AsyncLoginResource(AsyncAPIResource): + """Complete first-party Beeper app login""" + + @cached_property + def with_raw_response(self) -> AsyncLoginResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncLoginResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncLoginResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AsyncLoginResourceWithStreamingResponse(self) + + async def email( + self, + *, + email: str, + request: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """ + Send a sign-in code to the user email address. + + Args: + email: Email address to send the sign-in code to. + + request: Login request ID returned by the start step. + + 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 + """ + return await self._post( + "/v1/app/login/email", + body=await async_maybe_transform( + { + "email": email, + "request": request, + }, + login_email_params.LoginEmailParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + security={}, + ), + cast_to=object, + ) + + async def register( + self, + *, + accept_terms: Literal[True], + lead_token: str, + request: str, + username: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> LoginRegisterResponse: + """ + Create a Beeper account after the user chooses a username and accepts the Terms + of Use. + + Args: + accept_terms: Confirms that the user accepted the Terms of Use and acknowledged the Privacy + Policy. + + lead_token: Registration token returned by Beeper. + + request: Login request ID returned by the start step. + + username: Username selected by the user. + + 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 + """ + return await self._post( + "/v1/app/login/register", + body=await async_maybe_transform( + { + "accept_terms": accept_terms, + "lead_token": lead_token, + "request": request, + "username": username, + }, + login_register_params.LoginRegisterParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + security={}, + ), + cast_to=LoginRegisterResponse, + ) + + async def response( + self, + *, + request: str, + response: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> LoginResponseResponse: + """Finish sign-in with the code sent to the user email address. + + If the user needs a + new account, the response includes account creation copy and username + suggestions. + + Args: + request: Login request ID returned by the start step. + + response: Sign-in code from the user email. + + 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 + """ + return cast( + LoginResponseResponse, + await self._post( + "/v1/app/login/response", + body=await async_maybe_transform( + { + "request": request, + "response": response, + }, + login_response_params.LoginResponseParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + security={}, + ), + cast_to=cast( + Any, LoginResponseResponse + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + async def start( + 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, + ) -> LoginStartResponse: + """Start a first-party Beeper Desktop sign-in session.""" + return await self._post( + "/v1/app/login/start", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + security={}, + ), + cast_to=LoginStartResponse, + ) + + +class LoginResourceWithRawResponse: + def __init__(self, login: LoginResource) -> None: + self._login = login + + self.email = to_raw_response_wrapper( + login.email, + ) + self.register = to_raw_response_wrapper( + login.register, + ) + self.response = to_raw_response_wrapper( + login.response, + ) + self.start = to_raw_response_wrapper( + login.start, + ) + + +class AsyncLoginResourceWithRawResponse: + def __init__(self, login: AsyncLoginResource) -> None: + self._login = login + + self.email = async_to_raw_response_wrapper( + login.email, + ) + self.register = async_to_raw_response_wrapper( + login.register, + ) + self.response = async_to_raw_response_wrapper( + login.response, + ) + self.start = async_to_raw_response_wrapper( + login.start, + ) + + +class LoginResourceWithStreamingResponse: + def __init__(self, login: LoginResource) -> None: + self._login = login + + self.email = to_streamed_response_wrapper( + login.email, + ) + self.register = to_streamed_response_wrapper( + login.register, + ) + self.response = to_streamed_response_wrapper( + login.response, + ) + self.start = to_streamed_response_wrapper( + login.start, + ) + + +class AsyncLoginResourceWithStreamingResponse: + def __init__(self, login: AsyncLoginResource) -> None: + self._login = login + + self.email = async_to_streamed_response_wrapper( + login.email, + ) + self.register = async_to_streamed_response_wrapper( + login.register, + ) + self.response = async_to_streamed_response_wrapper( + login.response, + ) + self.start = async_to_streamed_response_wrapper( + login.start, + ) diff --git a/src/beeper_desktop_api/resources/bridges.py b/src/beeper_desktop_api/resources/bridges.py new file mode 100644 index 0000000..1d9e25a --- /dev/null +++ b/src/beeper_desktop_api/resources/bridges.py @@ -0,0 +1,145 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from .._types import Body, Query, Headers, NotGiven, not_given +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 +from ..types.bridge_list_response import BridgeListResponse + +__all__ = ["BridgesResource", "AsyncBridgesResource"] + + +class BridgesResource(SyncAPIResource): + """Manage bridge-backed account types and account availability""" + + @cached_property + def with_raw_response(self) -> BridgesResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return BridgesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> BridgesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return BridgesResourceWithStreamingResponse(self) + + def list( + 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, + ) -> BridgeListResponse: + """ + List bridge-backed account types that can be shown in add-account flows, grouped + with connected accounts that use the same Account schema as GET /v1/accounts. + """ + return self._get( + "/v1/bridges", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BridgeListResponse, + ) + + +class AsyncBridgesResource(AsyncAPIResource): + """Manage bridge-backed account types and account availability""" + + @cached_property + def with_raw_response(self) -> AsyncBridgesResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncBridgesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncBridgesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AsyncBridgesResourceWithStreamingResponse(self) + + async def list( + 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, + ) -> BridgeListResponse: + """ + List bridge-backed account types that can be shown in add-account flows, grouped + with connected accounts that use the same Account schema as GET /v1/accounts. + """ + return await self._get( + "/v1/bridges", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BridgeListResponse, + ) + + +class BridgesResourceWithRawResponse: + def __init__(self, bridges: BridgesResource) -> None: + self._bridges = bridges + + self.list = to_raw_response_wrapper( + bridges.list, + ) + + +class AsyncBridgesResourceWithRawResponse: + def __init__(self, bridges: AsyncBridgesResource) -> None: + self._bridges = bridges + + self.list = async_to_raw_response_wrapper( + bridges.list, + ) + + +class BridgesResourceWithStreamingResponse: + def __init__(self, bridges: BridgesResource) -> None: + self._bridges = bridges + + self.list = to_streamed_response_wrapper( + bridges.list, + ) + + +class AsyncBridgesResourceWithStreamingResponse: + def __init__(self, bridges: AsyncBridgesResource) -> None: + self._bridges = bridges + + self.list = async_to_streamed_response_wrapper( + bridges.list, + ) diff --git a/src/beeper_desktop_api/resources/matrix/__init__.py b/src/beeper_desktop_api/resources/matrix/__init__.py new file mode 100644 index 0000000..7d5901f --- /dev/null +++ b/src/beeper_desktop_api/resources/matrix/__init__.py @@ -0,0 +1,61 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .rooms import ( + RoomsResource, + AsyncRoomsResource, + RoomsResourceWithRawResponse, + AsyncRoomsResourceWithRawResponse, + RoomsResourceWithStreamingResponse, + AsyncRoomsResourceWithStreamingResponse, +) +from .users import ( + UsersResource, + AsyncUsersResource, + UsersResourceWithRawResponse, + AsyncUsersResourceWithRawResponse, + UsersResourceWithStreamingResponse, + AsyncUsersResourceWithStreamingResponse, +) +from .matrix import ( + MatrixResource, + AsyncMatrixResource, + MatrixResourceWithRawResponse, + AsyncMatrixResourceWithRawResponse, + MatrixResourceWithStreamingResponse, + AsyncMatrixResourceWithStreamingResponse, +) +from .bridges import ( + BridgesResource, + AsyncBridgesResource, + BridgesResourceWithRawResponse, + AsyncBridgesResourceWithRawResponse, + BridgesResourceWithStreamingResponse, + AsyncBridgesResourceWithStreamingResponse, +) + +__all__ = [ + "UsersResource", + "AsyncUsersResource", + "UsersResourceWithRawResponse", + "AsyncUsersResourceWithRawResponse", + "UsersResourceWithStreamingResponse", + "AsyncUsersResourceWithStreamingResponse", + "RoomsResource", + "AsyncRoomsResource", + "RoomsResourceWithRawResponse", + "AsyncRoomsResourceWithRawResponse", + "RoomsResourceWithStreamingResponse", + "AsyncRoomsResourceWithStreamingResponse", + "BridgesResource", + "AsyncBridgesResource", + "BridgesResourceWithRawResponse", + "AsyncBridgesResourceWithRawResponse", + "BridgesResourceWithStreamingResponse", + "AsyncBridgesResourceWithStreamingResponse", + "MatrixResource", + "AsyncMatrixResource", + "MatrixResourceWithRawResponse", + "AsyncMatrixResourceWithRawResponse", + "MatrixResourceWithStreamingResponse", + "AsyncMatrixResourceWithStreamingResponse", +] diff --git a/src/beeper_desktop_api/resources/matrix/bridges/__init__.py b/src/beeper_desktop_api/resources/matrix/bridges/__init__.py new file mode 100644 index 0000000..e25079a --- /dev/null +++ b/src/beeper_desktop_api/resources/matrix/bridges/__init__.py @@ -0,0 +1,89 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .auth import ( + AuthResource, + AsyncAuthResource, + AuthResourceWithRawResponse, + AsyncAuthResourceWithRawResponse, + AuthResourceWithStreamingResponse, + AsyncAuthResourceWithStreamingResponse, +) +from .rooms import ( + RoomsResource, + AsyncRoomsResource, + RoomsResourceWithRawResponse, + AsyncRoomsResourceWithRawResponse, + RoomsResourceWithStreamingResponse, + AsyncRoomsResourceWithStreamingResponse, +) +from .users import ( + UsersResource, + AsyncUsersResource, + UsersResourceWithRawResponse, + AsyncUsersResourceWithRawResponse, + UsersResourceWithStreamingResponse, + AsyncUsersResourceWithStreamingResponse, +) +from .bridges import ( + BridgesResource, + AsyncBridgesResource, + BridgesResourceWithRawResponse, + AsyncBridgesResourceWithRawResponse, + BridgesResourceWithStreamingResponse, + AsyncBridgesResourceWithStreamingResponse, +) +from .contacts import ( + ContactsResource, + AsyncContactsResource, + ContactsResourceWithRawResponse, + AsyncContactsResourceWithRawResponse, + ContactsResourceWithStreamingResponse, + AsyncContactsResourceWithStreamingResponse, +) +from .capabilities import ( + CapabilitiesResource, + AsyncCapabilitiesResource, + CapabilitiesResourceWithRawResponse, + AsyncCapabilitiesResourceWithRawResponse, + CapabilitiesResourceWithStreamingResponse, + AsyncCapabilitiesResourceWithStreamingResponse, +) + +__all__ = [ + "AuthResource", + "AsyncAuthResource", + "AuthResourceWithRawResponse", + "AsyncAuthResourceWithRawResponse", + "AuthResourceWithStreamingResponse", + "AsyncAuthResourceWithStreamingResponse", + "ContactsResource", + "AsyncContactsResource", + "ContactsResourceWithRawResponse", + "AsyncContactsResourceWithRawResponse", + "ContactsResourceWithStreamingResponse", + "AsyncContactsResourceWithStreamingResponse", + "UsersResource", + "AsyncUsersResource", + "UsersResourceWithRawResponse", + "AsyncUsersResourceWithRawResponse", + "UsersResourceWithStreamingResponse", + "AsyncUsersResourceWithStreamingResponse", + "RoomsResource", + "AsyncRoomsResource", + "RoomsResourceWithRawResponse", + "AsyncRoomsResourceWithRawResponse", + "RoomsResourceWithStreamingResponse", + "AsyncRoomsResourceWithStreamingResponse", + "CapabilitiesResource", + "AsyncCapabilitiesResource", + "CapabilitiesResourceWithRawResponse", + "AsyncCapabilitiesResourceWithRawResponse", + "CapabilitiesResourceWithStreamingResponse", + "AsyncCapabilitiesResourceWithStreamingResponse", + "BridgesResource", + "AsyncBridgesResource", + "BridgesResourceWithRawResponse", + "AsyncBridgesResourceWithRawResponse", + "BridgesResourceWithStreamingResponse", + "AsyncBridgesResourceWithStreamingResponse", +] diff --git a/src/beeper_desktop_api/resources/matrix/bridges/auth.py b/src/beeper_desktop_api/resources/matrix/bridges/auth.py new file mode 100644 index 0000000..b05ee19 --- /dev/null +++ b/src/beeper_desktop_api/resources/matrix/bridges/auth.py @@ -0,0 +1,951 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Any, Dict, cast + +import httpx + +from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +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 +from ....types.matrix.bridges import auth_start_login_params, auth_submit_cookies_params, auth_submit_user_input_params +from ....types.matrix.bridges.auth_whoami_response import AuthWhoamiResponse +from ....types.matrix.bridges.auth_list_flows_response import AuthListFlowsResponse +from ....types.matrix.bridges.auth_list_logins_response import AuthListLoginsResponse +from ....types.matrix.bridges.auth_start_login_response import AuthStartLoginResponse +from ....types.matrix.bridges.auth_wait_for_step_response import AuthWaitForStepResponse +from ....types.matrix.bridges.auth_submit_cookies_response import AuthSubmitCookiesResponse +from ....types.matrix.bridges.auth_submit_user_input_response import AuthSubmitUserInputResponse + +__all__ = ["AuthResource", "AsyncAuthResource"] + + +class AuthResource(SyncAPIResource): + """Matrix-compatible APIs for accounts and connected network bridges.""" + + @cached_property + def with_raw_response(self) -> AuthResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AuthResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AuthResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AuthResourceWithStreamingResponse(self) + + def list_flows( + self, + bridge_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AuthListFlowsResponse: + """ + Get the available login flows. + + Args: + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + return self._get( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/login/flows", + bridge_id=bridge_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AuthListFlowsResponse, + ) + + def list_logins( + self, + bridge_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AuthListLoginsResponse: + """ + Get the login IDs of the current user. + + Args: + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + return self._get( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/logins", + bridge_id=bridge_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AuthListLoginsResponse, + ) + + def logout( + self, + login_id: str, + *, + bridge_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """Log out of an existing login. + + Args: + login_id: The unique ID of a login. + + Defined by the network connector. + + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + if not login_id: + raise ValueError(f"Expected a non-empty value for `login_id` but received {login_id!r}") + return self._post( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/logout/{login_id}", + bridge_id=bridge_id, + login_id=login_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=object, + ) + + def start_login( + self, + flow_id: str, + *, + bridge_id: str, + login_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AuthStartLoginResponse: + """ + This endpoint starts a new login process, which is used to log into the bridge. + + The basic flow of the entire login, including calling this endpoint, is: + + 1. Call `GET /v3/login/flows` to get the list of available flows. If there's + more than one flow, ask the user to pick which one they want to use. + 2. Call this endpoint with the chosen flow ID to start the login. The first + login step will be returned. + 3. Render the information provided in the step. + 4. Call the `/login/step/...` endpoint corresponding to the step type: + - For `user_input` and `cookies`, acquire the requested fields before calling + the endpoint. + - For `display_and_wait`, call the endpoint immediately (as there's nothing + to acquire on the client side). + 5. Handle the data returned by the login step endpoint: + - If an error is returned, the login has failed and must be restarted (from + either step 1 or step 2) if the user wants to try again. + - If step type `complete` is returned, the login finished successfully. + - Otherwise, go to step 3 with the new data. + + Args: + login_id: An existing login ID to re-login as. If this is specified and the user logs into + a different account, the provided ID will be logged out. + + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + if not flow_id: + raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") + return cast( + AuthStartLoginResponse, + self._post( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/login/start/{flow_id}", + bridge_id=bridge_id, + flow_id=flow_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform({"login_id": login_id}, auth_start_login_params.AuthStartLoginParams), + ), + cast_to=cast( + Any, AuthStartLoginResponse + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + def submit_cookies( + self, + step_id: str, + *, + bridge_id: str, + login_process_id: str, + body: Dict[str, 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AuthSubmitCookiesResponse: + """ + Submit extracted cookies in a login process. + + Args: + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + if not login_process_id: + raise ValueError(f"Expected a non-empty value for `login_process_id` but received {login_process_id!r}") + if not step_id: + raise ValueError(f"Expected a non-empty value for `step_id` but received {step_id!r}") + return cast( + AuthSubmitCookiesResponse, + self._post( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/login/step/{login_process_id}/{step_id}/cookies", + bridge_id=bridge_id, + login_process_id=login_process_id, + step_id=step_id, + ), + body=maybe_transform(body, auth_submit_cookies_params.AuthSubmitCookiesParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=cast( + Any, AuthSubmitCookiesResponse + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + def submit_user_input( + self, + step_id: str, + *, + bridge_id: str, + login_process_id: str, + body: Dict[str, 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AuthSubmitUserInputResponse: + """ + Submit user input in a login process. + + Args: + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + if not login_process_id: + raise ValueError(f"Expected a non-empty value for `login_process_id` but received {login_process_id!r}") + if not step_id: + raise ValueError(f"Expected a non-empty value for `step_id` but received {step_id!r}") + return cast( + AuthSubmitUserInputResponse, + self._post( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/login/step/{login_process_id}/{step_id}/user_input", + bridge_id=bridge_id, + login_process_id=login_process_id, + step_id=step_id, + ), + body=maybe_transform(body, auth_submit_user_input_params.AuthSubmitUserInputParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=cast( + Any, AuthSubmitUserInputResponse + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + def wait_for_step( + self, + step_id: str, + *, + bridge_id: str, + login_process_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AuthWaitForStepResponse: + """ + Wait for the next step after displaying data to the user. + + Args: + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + if not login_process_id: + raise ValueError(f"Expected a non-empty value for `login_process_id` but received {login_process_id!r}") + if not step_id: + raise ValueError(f"Expected a non-empty value for `step_id` but received {step_id!r}") + return cast( + AuthWaitForStepResponse, + self._post( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/login/step/{login_process_id}/{step_id}/display_and_wait", + bridge_id=bridge_id, + login_process_id=login_process_id, + step_id=step_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=cast( + Any, AuthWaitForStepResponse + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + def whoami( + self, + bridge_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AuthWhoamiResponse: + """ + Get all info that is useful for presenting this bridge in a manager interface. + + - Server details: remote network details, available login flows, homeserver + name, bridge bot user ID, command prefix + - User details: management room ID, list of logins with current state and info + + Args: + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + return self._get( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/whoami", + bridge_id=bridge_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AuthWhoamiResponse, + ) + + +class AsyncAuthResource(AsyncAPIResource): + """Matrix-compatible APIs for accounts and connected network bridges.""" + + @cached_property + def with_raw_response(self) -> AsyncAuthResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncAuthResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncAuthResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AsyncAuthResourceWithStreamingResponse(self) + + async def list_flows( + self, + bridge_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AuthListFlowsResponse: + """ + Get the available login flows. + + Args: + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + return await self._get( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/login/flows", + bridge_id=bridge_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AuthListFlowsResponse, + ) + + async def list_logins( + self, + bridge_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AuthListLoginsResponse: + """ + Get the login IDs of the current user. + + Args: + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + return await self._get( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/logins", + bridge_id=bridge_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AuthListLoginsResponse, + ) + + async def logout( + self, + login_id: str, + *, + bridge_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """Log out of an existing login. + + Args: + login_id: The unique ID of a login. + + Defined by the network connector. + + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + if not login_id: + raise ValueError(f"Expected a non-empty value for `login_id` but received {login_id!r}") + return await self._post( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/logout/{login_id}", + bridge_id=bridge_id, + login_id=login_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=object, + ) + + async def start_login( + self, + flow_id: str, + *, + bridge_id: str, + login_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AuthStartLoginResponse: + """ + This endpoint starts a new login process, which is used to log into the bridge. + + The basic flow of the entire login, including calling this endpoint, is: + + 1. Call `GET /v3/login/flows` to get the list of available flows. If there's + more than one flow, ask the user to pick which one they want to use. + 2. Call this endpoint with the chosen flow ID to start the login. The first + login step will be returned. + 3. Render the information provided in the step. + 4. Call the `/login/step/...` endpoint corresponding to the step type: + - For `user_input` and `cookies`, acquire the requested fields before calling + the endpoint. + - For `display_and_wait`, call the endpoint immediately (as there's nothing + to acquire on the client side). + 5. Handle the data returned by the login step endpoint: + - If an error is returned, the login has failed and must be restarted (from + either step 1 or step 2) if the user wants to try again. + - If step type `complete` is returned, the login finished successfully. + - Otherwise, go to step 3 with the new data. + + Args: + login_id: An existing login ID to re-login as. If this is specified and the user logs into + a different account, the provided ID will be logged out. + + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + if not flow_id: + raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") + return cast( + AuthStartLoginResponse, + await self._post( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/login/start/{flow_id}", + bridge_id=bridge_id, + flow_id=flow_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + {"login_id": login_id}, auth_start_login_params.AuthStartLoginParams + ), + ), + cast_to=cast( + Any, AuthStartLoginResponse + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + async def submit_cookies( + self, + step_id: str, + *, + bridge_id: str, + login_process_id: str, + body: Dict[str, 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AuthSubmitCookiesResponse: + """ + Submit extracted cookies in a login process. + + Args: + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + if not login_process_id: + raise ValueError(f"Expected a non-empty value for `login_process_id` but received {login_process_id!r}") + if not step_id: + raise ValueError(f"Expected a non-empty value for `step_id` but received {step_id!r}") + return cast( + AuthSubmitCookiesResponse, + await self._post( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/login/step/{login_process_id}/{step_id}/cookies", + bridge_id=bridge_id, + login_process_id=login_process_id, + step_id=step_id, + ), + body=await async_maybe_transform(body, auth_submit_cookies_params.AuthSubmitCookiesParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=cast( + Any, AuthSubmitCookiesResponse + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + async def submit_user_input( + self, + step_id: str, + *, + bridge_id: str, + login_process_id: str, + body: Dict[str, 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AuthSubmitUserInputResponse: + """ + Submit user input in a login process. + + Args: + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + if not login_process_id: + raise ValueError(f"Expected a non-empty value for `login_process_id` but received {login_process_id!r}") + if not step_id: + raise ValueError(f"Expected a non-empty value for `step_id` but received {step_id!r}") + return cast( + AuthSubmitUserInputResponse, + await self._post( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/login/step/{login_process_id}/{step_id}/user_input", + bridge_id=bridge_id, + login_process_id=login_process_id, + step_id=step_id, + ), + body=await async_maybe_transform(body, auth_submit_user_input_params.AuthSubmitUserInputParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=cast( + Any, AuthSubmitUserInputResponse + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + async def wait_for_step( + self, + step_id: str, + *, + bridge_id: str, + login_process_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AuthWaitForStepResponse: + """ + Wait for the next step after displaying data to the user. + + Args: + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + if not login_process_id: + raise ValueError(f"Expected a non-empty value for `login_process_id` but received {login_process_id!r}") + if not step_id: + raise ValueError(f"Expected a non-empty value for `step_id` but received {step_id!r}") + return cast( + AuthWaitForStepResponse, + await self._post( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/login/step/{login_process_id}/{step_id}/display_and_wait", + bridge_id=bridge_id, + login_process_id=login_process_id, + step_id=step_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=cast( + Any, AuthWaitForStepResponse + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + async def whoami( + self, + bridge_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AuthWhoamiResponse: + """ + Get all info that is useful for presenting this bridge in a manager interface. + + - Server details: remote network details, available login flows, homeserver + name, bridge bot user ID, command prefix + - User details: management room ID, list of logins with current state and info + + Args: + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + return await self._get( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/whoami", + bridge_id=bridge_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AuthWhoamiResponse, + ) + + +class AuthResourceWithRawResponse: + def __init__(self, auth: AuthResource) -> None: + self._auth = auth + + self.list_flows = to_raw_response_wrapper( + auth.list_flows, + ) + self.list_logins = to_raw_response_wrapper( + auth.list_logins, + ) + self.logout = to_raw_response_wrapper( + auth.logout, + ) + self.start_login = to_raw_response_wrapper( + auth.start_login, + ) + self.submit_cookies = to_raw_response_wrapper( + auth.submit_cookies, + ) + self.submit_user_input = to_raw_response_wrapper( + auth.submit_user_input, + ) + self.wait_for_step = to_raw_response_wrapper( + auth.wait_for_step, + ) + self.whoami = to_raw_response_wrapper( + auth.whoami, + ) + + +class AsyncAuthResourceWithRawResponse: + def __init__(self, auth: AsyncAuthResource) -> None: + self._auth = auth + + self.list_flows = async_to_raw_response_wrapper( + auth.list_flows, + ) + self.list_logins = async_to_raw_response_wrapper( + auth.list_logins, + ) + self.logout = async_to_raw_response_wrapper( + auth.logout, + ) + self.start_login = async_to_raw_response_wrapper( + auth.start_login, + ) + self.submit_cookies = async_to_raw_response_wrapper( + auth.submit_cookies, + ) + self.submit_user_input = async_to_raw_response_wrapper( + auth.submit_user_input, + ) + self.wait_for_step = async_to_raw_response_wrapper( + auth.wait_for_step, + ) + self.whoami = async_to_raw_response_wrapper( + auth.whoami, + ) + + +class AuthResourceWithStreamingResponse: + def __init__(self, auth: AuthResource) -> None: + self._auth = auth + + self.list_flows = to_streamed_response_wrapper( + auth.list_flows, + ) + self.list_logins = to_streamed_response_wrapper( + auth.list_logins, + ) + self.logout = to_streamed_response_wrapper( + auth.logout, + ) + self.start_login = to_streamed_response_wrapper( + auth.start_login, + ) + self.submit_cookies = to_streamed_response_wrapper( + auth.submit_cookies, + ) + self.submit_user_input = to_streamed_response_wrapper( + auth.submit_user_input, + ) + self.wait_for_step = to_streamed_response_wrapper( + auth.wait_for_step, + ) + self.whoami = to_streamed_response_wrapper( + auth.whoami, + ) + + +class AsyncAuthResourceWithStreamingResponse: + def __init__(self, auth: AsyncAuthResource) -> None: + self._auth = auth + + self.list_flows = async_to_streamed_response_wrapper( + auth.list_flows, + ) + self.list_logins = async_to_streamed_response_wrapper( + auth.list_logins, + ) + self.logout = async_to_streamed_response_wrapper( + auth.logout, + ) + self.start_login = async_to_streamed_response_wrapper( + auth.start_login, + ) + self.submit_cookies = async_to_streamed_response_wrapper( + auth.submit_cookies, + ) + self.submit_user_input = async_to_streamed_response_wrapper( + auth.submit_user_input, + ) + self.wait_for_step = async_to_streamed_response_wrapper( + auth.wait_for_step, + ) + self.whoami = async_to_streamed_response_wrapper( + auth.whoami, + ) diff --git a/src/beeper_desktop_api/resources/matrix/bridges/bridges.py b/src/beeper_desktop_api/resources/matrix/bridges/bridges.py new file mode 100644 index 0000000..f2922c9 --- /dev/null +++ b/src/beeper_desktop_api/resources/matrix/bridges/bridges.py @@ -0,0 +1,264 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .auth import ( + AuthResource, + AsyncAuthResource, + AuthResourceWithRawResponse, + AsyncAuthResourceWithRawResponse, + AuthResourceWithStreamingResponse, + AsyncAuthResourceWithStreamingResponse, +) +from .rooms import ( + RoomsResource, + AsyncRoomsResource, + RoomsResourceWithRawResponse, + AsyncRoomsResourceWithRawResponse, + RoomsResourceWithStreamingResponse, + AsyncRoomsResourceWithStreamingResponse, +) +from .users import ( + UsersResource, + AsyncUsersResource, + UsersResourceWithRawResponse, + AsyncUsersResourceWithRawResponse, + UsersResourceWithStreamingResponse, + AsyncUsersResourceWithStreamingResponse, +) +from .contacts import ( + ContactsResource, + AsyncContactsResource, + ContactsResourceWithRawResponse, + AsyncContactsResourceWithRawResponse, + ContactsResourceWithStreamingResponse, + AsyncContactsResourceWithStreamingResponse, +) +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from .capabilities import ( + CapabilitiesResource, + AsyncCapabilitiesResource, + CapabilitiesResourceWithRawResponse, + AsyncCapabilitiesResourceWithRawResponse, + CapabilitiesResourceWithStreamingResponse, + AsyncCapabilitiesResourceWithStreamingResponse, +) + +__all__ = ["BridgesResource", "AsyncBridgesResource"] + + +class BridgesResource(SyncAPIResource): + """Matrix-compatible APIs for connected network bridges.""" + + @cached_property + def auth(self) -> AuthResource: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return AuthResource(self._client) + + @cached_property + def contacts(self) -> ContactsResource: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return ContactsResource(self._client) + + @cached_property + def users(self) -> UsersResource: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return UsersResource(self._client) + + @cached_property + def rooms(self) -> RoomsResource: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return RoomsResource(self._client) + + @cached_property + def capabilities(self) -> CapabilitiesResource: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return CapabilitiesResource(self._client) + + @cached_property + def with_raw_response(self) -> BridgesResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return BridgesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> BridgesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return BridgesResourceWithStreamingResponse(self) + + +class AsyncBridgesResource(AsyncAPIResource): + """Matrix-compatible APIs for connected network bridges.""" + + @cached_property + def auth(self) -> AsyncAuthResource: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return AsyncAuthResource(self._client) + + @cached_property + def contacts(self) -> AsyncContactsResource: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return AsyncContactsResource(self._client) + + @cached_property + def users(self) -> AsyncUsersResource: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return AsyncUsersResource(self._client) + + @cached_property + def rooms(self) -> AsyncRoomsResource: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return AsyncRoomsResource(self._client) + + @cached_property + def capabilities(self) -> AsyncCapabilitiesResource: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return AsyncCapabilitiesResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncBridgesResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncBridgesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncBridgesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AsyncBridgesResourceWithStreamingResponse(self) + + +class BridgesResourceWithRawResponse: + def __init__(self, bridges: BridgesResource) -> None: + self._bridges = bridges + + @cached_property + def auth(self) -> AuthResourceWithRawResponse: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return AuthResourceWithRawResponse(self._bridges.auth) + + @cached_property + def contacts(self) -> ContactsResourceWithRawResponse: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return ContactsResourceWithRawResponse(self._bridges.contacts) + + @cached_property + def users(self) -> UsersResourceWithRawResponse: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return UsersResourceWithRawResponse(self._bridges.users) + + @cached_property + def rooms(self) -> RoomsResourceWithRawResponse: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return RoomsResourceWithRawResponse(self._bridges.rooms) + + @cached_property + def capabilities(self) -> CapabilitiesResourceWithRawResponse: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return CapabilitiesResourceWithRawResponse(self._bridges.capabilities) + + +class AsyncBridgesResourceWithRawResponse: + def __init__(self, bridges: AsyncBridgesResource) -> None: + self._bridges = bridges + + @cached_property + def auth(self) -> AsyncAuthResourceWithRawResponse: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return AsyncAuthResourceWithRawResponse(self._bridges.auth) + + @cached_property + def contacts(self) -> AsyncContactsResourceWithRawResponse: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return AsyncContactsResourceWithRawResponse(self._bridges.contacts) + + @cached_property + def users(self) -> AsyncUsersResourceWithRawResponse: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return AsyncUsersResourceWithRawResponse(self._bridges.users) + + @cached_property + def rooms(self) -> AsyncRoomsResourceWithRawResponse: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return AsyncRoomsResourceWithRawResponse(self._bridges.rooms) + + @cached_property + def capabilities(self) -> AsyncCapabilitiesResourceWithRawResponse: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return AsyncCapabilitiesResourceWithRawResponse(self._bridges.capabilities) + + +class BridgesResourceWithStreamingResponse: + def __init__(self, bridges: BridgesResource) -> None: + self._bridges = bridges + + @cached_property + def auth(self) -> AuthResourceWithStreamingResponse: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return AuthResourceWithStreamingResponse(self._bridges.auth) + + @cached_property + def contacts(self) -> ContactsResourceWithStreamingResponse: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return ContactsResourceWithStreamingResponse(self._bridges.contacts) + + @cached_property + def users(self) -> UsersResourceWithStreamingResponse: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return UsersResourceWithStreamingResponse(self._bridges.users) + + @cached_property + def rooms(self) -> RoomsResourceWithStreamingResponse: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return RoomsResourceWithStreamingResponse(self._bridges.rooms) + + @cached_property + def capabilities(self) -> CapabilitiesResourceWithStreamingResponse: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return CapabilitiesResourceWithStreamingResponse(self._bridges.capabilities) + + +class AsyncBridgesResourceWithStreamingResponse: + def __init__(self, bridges: AsyncBridgesResource) -> None: + self._bridges = bridges + + @cached_property + def auth(self) -> AsyncAuthResourceWithStreamingResponse: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return AsyncAuthResourceWithStreamingResponse(self._bridges.auth) + + @cached_property + def contacts(self) -> AsyncContactsResourceWithStreamingResponse: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return AsyncContactsResourceWithStreamingResponse(self._bridges.contacts) + + @cached_property + def users(self) -> AsyncUsersResourceWithStreamingResponse: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return AsyncUsersResourceWithStreamingResponse(self._bridges.users) + + @cached_property + def rooms(self) -> AsyncRoomsResourceWithStreamingResponse: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return AsyncRoomsResourceWithStreamingResponse(self._bridges.rooms) + + @cached_property + def capabilities(self) -> AsyncCapabilitiesResourceWithStreamingResponse: + """Matrix-compatible APIs for accounts and connected network bridges.""" + return AsyncCapabilitiesResourceWithStreamingResponse(self._bridges.capabilities) diff --git a/src/beeper_desktop_api/resources/matrix/bridges/capabilities.py b/src/beeper_desktop_api/resources/matrix/bridges/capabilities.py new file mode 100644 index 0000000..48338bc --- /dev/null +++ b/src/beeper_desktop_api/resources/matrix/bridges/capabilities.py @@ -0,0 +1,174 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ...._types import Body, Query, Headers, NotGiven, not_given +from ...._utils import path_template +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 +from ....types.matrix.bridges.capability_retrieve_response import CapabilityRetrieveResponse + +__all__ = ["CapabilitiesResource", "AsyncCapabilitiesResource"] + + +class CapabilitiesResource(SyncAPIResource): + """Matrix-compatible APIs for accounts and connected network bridges.""" + + @cached_property + def with_raw_response(self) -> CapabilitiesResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return CapabilitiesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> CapabilitiesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return CapabilitiesResourceWithStreamingResponse(self) + + def retrieve( + self, + bridge_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> CapabilityRetrieveResponse: + """ + Get bridge capabilities + + Args: + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + return self._get( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/capabilities", + bridge_id=bridge_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=CapabilityRetrieveResponse, + ) + + +class AsyncCapabilitiesResource(AsyncAPIResource): + """Matrix-compatible APIs for accounts and connected network bridges.""" + + @cached_property + def with_raw_response(self) -> AsyncCapabilitiesResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncCapabilitiesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncCapabilitiesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AsyncCapabilitiesResourceWithStreamingResponse(self) + + async def retrieve( + self, + bridge_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> CapabilityRetrieveResponse: + """ + Get bridge capabilities + + Args: + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + return await self._get( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/capabilities", + bridge_id=bridge_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=CapabilityRetrieveResponse, + ) + + +class CapabilitiesResourceWithRawResponse: + def __init__(self, capabilities: CapabilitiesResource) -> None: + self._capabilities = capabilities + + self.retrieve = to_raw_response_wrapper( + capabilities.retrieve, + ) + + +class AsyncCapabilitiesResourceWithRawResponse: + def __init__(self, capabilities: AsyncCapabilitiesResource) -> None: + self._capabilities = capabilities + + self.retrieve = async_to_raw_response_wrapper( + capabilities.retrieve, + ) + + +class CapabilitiesResourceWithStreamingResponse: + def __init__(self, capabilities: CapabilitiesResource) -> None: + self._capabilities = capabilities + + self.retrieve = to_streamed_response_wrapper( + capabilities.retrieve, + ) + + +class AsyncCapabilitiesResourceWithStreamingResponse: + def __init__(self, capabilities: AsyncCapabilitiesResource) -> None: + self._capabilities = capabilities + + self.retrieve = async_to_streamed_response_wrapper( + capabilities.retrieve, + ) diff --git a/src/beeper_desktop_api/resources/matrix/bridges/contacts.py b/src/beeper_desktop_api/resources/matrix/bridges/contacts.py new file mode 100644 index 0000000..1b7c10b --- /dev/null +++ b/src/beeper_desktop_api/resources/matrix/bridges/contacts.py @@ -0,0 +1,189 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +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 +from ....types.matrix.bridges import contact_list_params +from ....types.matrix.bridges.contact_list_response import ContactListResponse + +__all__ = ["ContactsResource", "AsyncContactsResource"] + + +class ContactsResource(SyncAPIResource): + """Matrix-compatible APIs for accounts and connected network bridges.""" + + @cached_property + def with_raw_response(self) -> ContactsResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return ContactsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> ContactsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return ContactsResourceWithStreamingResponse(self) + + def list( + self, + bridge_id: str, + *, + login_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> ContactListResponse: + """ + Get a list of contacts. + + Args: + login_id: An optional explicit login ID to do the action through. + + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + return self._get( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/contacts", + bridge_id=bridge_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform({"login_id": login_id}, contact_list_params.ContactListParams), + ), + cast_to=ContactListResponse, + ) + + +class AsyncContactsResource(AsyncAPIResource): + """Matrix-compatible APIs for accounts and connected network bridges.""" + + @cached_property + def with_raw_response(self) -> AsyncContactsResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncContactsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncContactsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AsyncContactsResourceWithStreamingResponse(self) + + async def list( + self, + bridge_id: str, + *, + login_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> ContactListResponse: + """ + Get a list of contacts. + + Args: + login_id: An optional explicit login ID to do the action through. + + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + return await self._get( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/contacts", + bridge_id=bridge_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform({"login_id": login_id}, contact_list_params.ContactListParams), + ), + cast_to=ContactListResponse, + ) + + +class ContactsResourceWithRawResponse: + def __init__(self, contacts: ContactsResource) -> None: + self._contacts = contacts + + self.list = to_raw_response_wrapper( + contacts.list, + ) + + +class AsyncContactsResourceWithRawResponse: + def __init__(self, contacts: AsyncContactsResource) -> None: + self._contacts = contacts + + self.list = async_to_raw_response_wrapper( + contacts.list, + ) + + +class ContactsResourceWithStreamingResponse: + def __init__(self, contacts: ContactsResource) -> None: + self._contacts = contacts + + self.list = to_streamed_response_wrapper( + contacts.list, + ) + + +class AsyncContactsResourceWithStreamingResponse: + def __init__(self, contacts: AsyncContactsResource) -> None: + self._contacts = contacts + + self.list = async_to_streamed_response_wrapper( + contacts.list, + ) diff --git a/src/beeper_desktop_api/resources/matrix/bridges/rooms.py b/src/beeper_desktop_api/resources/matrix/bridges/rooms.py new file mode 100644 index 0000000..fcd9d9b --- /dev/null +++ b/src/beeper_desktop_api/resources/matrix/bridges/rooms.py @@ -0,0 +1,386 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ...._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +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 +from ....types.matrix.bridges import room_create_dm_params, room_create_group_params +from ....types.matrix.bridges.room_create_dm_response import RoomCreateDmResponse +from ....types.matrix.bridges.room_create_group_response import RoomCreateGroupResponse + +__all__ = ["RoomsResource", "AsyncRoomsResource"] + + +class RoomsResource(SyncAPIResource): + """Matrix-compatible APIs for accounts and connected network bridges.""" + + @cached_property + def with_raw_response(self) -> RoomsResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return RoomsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> RoomsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return RoomsResourceWithStreamingResponse(self) + + def create_dm( + self, + identifier: str, + *, + bridge_id: str, + login_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RoomCreateDmResponse: + """ + Create a direct chat with a user on the remote network. + + Args: + login_id: An optional explicit login ID to do the action through. + + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + if not identifier: + raise ValueError(f"Expected a non-empty value for `identifier` but received {identifier!r}") + return self._post( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/create_dm/{identifier}", + bridge_id=bridge_id, + identifier=identifier, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform({"login_id": login_id}, room_create_dm_params.RoomCreateDmParams), + ), + cast_to=RoomCreateDmResponse, + ) + + def create_group( + self, + group_type: str, + *, + bridge_id: str, + login_id: str | Omit = omit, + avatar: room_create_group_params.Avatar | Omit = omit, + disappear: room_create_group_params.Disappear | Omit = omit, + name: room_create_group_params.Name | Omit = omit, + parent: object | Omit = omit, + participants: SequenceNotStr[str] | Omit = omit, + room_id: str | Omit = omit, + topic: room_create_group_params.Topic | Omit = omit, + type: str | Omit = omit, + username: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RoomCreateGroupResponse: + """ + Create a group chat on the remote network. + + Args: + login_id: An optional explicit login ID to do the action through. + + avatar: The `m.room.avatar` event content for the room. + + disappear: The `com.beeper.disappearing_timer` event content for the room. + + name: The `m.room.name` event content for the room. + + participants: The users to add to the group initially. + + room_id: An existing Matrix room ID to bridge to. The other parameters must be already in + sync with the room state when using this parameter. + + topic: The `m.room.topic` event content for the room. + + type: The type of group to create. + + username: The public username for the created group. + + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + if not group_type: + raise ValueError(f"Expected a non-empty value for `group_type` but received {group_type!r}") + return self._post( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/create_group/{group_type}", + bridge_id=bridge_id, + group_type=group_type, + ), + body=maybe_transform( + { + "avatar": avatar, + "disappear": disappear, + "name": name, + "parent": parent, + "participants": participants, + "room_id": room_id, + "topic": topic, + "type": type, + "username": username, + }, + room_create_group_params.RoomCreateGroupParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform({"login_id": login_id}, room_create_group_params.RoomCreateGroupParams), + ), + cast_to=RoomCreateGroupResponse, + ) + + +class AsyncRoomsResource(AsyncAPIResource): + """Matrix-compatible APIs for accounts and connected network bridges.""" + + @cached_property + def with_raw_response(self) -> AsyncRoomsResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncRoomsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncRoomsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AsyncRoomsResourceWithStreamingResponse(self) + + async def create_dm( + self, + identifier: str, + *, + bridge_id: str, + login_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RoomCreateDmResponse: + """ + Create a direct chat with a user on the remote network. + + Args: + login_id: An optional explicit login ID to do the action through. + + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + if not identifier: + raise ValueError(f"Expected a non-empty value for `identifier` but received {identifier!r}") + return await self._post( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/create_dm/{identifier}", + bridge_id=bridge_id, + identifier=identifier, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform({"login_id": login_id}, room_create_dm_params.RoomCreateDmParams), + ), + cast_to=RoomCreateDmResponse, + ) + + async def create_group( + self, + group_type: str, + *, + bridge_id: str, + login_id: str | Omit = omit, + avatar: room_create_group_params.Avatar | Omit = omit, + disappear: room_create_group_params.Disappear | Omit = omit, + name: room_create_group_params.Name | Omit = omit, + parent: object | Omit = omit, + participants: SequenceNotStr[str] | Omit = omit, + room_id: str | Omit = omit, + topic: room_create_group_params.Topic | Omit = omit, + type: str | Omit = omit, + username: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RoomCreateGroupResponse: + """ + Create a group chat on the remote network. + + Args: + login_id: An optional explicit login ID to do the action through. + + avatar: The `m.room.avatar` event content for the room. + + disappear: The `com.beeper.disappearing_timer` event content for the room. + + name: The `m.room.name` event content for the room. + + participants: The users to add to the group initially. + + room_id: An existing Matrix room ID to bridge to. The other parameters must be already in + sync with the room state when using this parameter. + + topic: The `m.room.topic` event content for the room. + + type: The type of group to create. + + username: The public username for the created group. + + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + if not group_type: + raise ValueError(f"Expected a non-empty value for `group_type` but received {group_type!r}") + return await self._post( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/create_group/{group_type}", + bridge_id=bridge_id, + group_type=group_type, + ), + body=await async_maybe_transform( + { + "avatar": avatar, + "disappear": disappear, + "name": name, + "parent": parent, + "participants": participants, + "room_id": room_id, + "topic": topic, + "type": type, + "username": username, + }, + room_create_group_params.RoomCreateGroupParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + {"login_id": login_id}, room_create_group_params.RoomCreateGroupParams + ), + ), + cast_to=RoomCreateGroupResponse, + ) + + +class RoomsResourceWithRawResponse: + def __init__(self, rooms: RoomsResource) -> None: + self._rooms = rooms + + self.create_dm = to_raw_response_wrapper( + rooms.create_dm, + ) + self.create_group = to_raw_response_wrapper( + rooms.create_group, + ) + + +class AsyncRoomsResourceWithRawResponse: + def __init__(self, rooms: AsyncRoomsResource) -> None: + self._rooms = rooms + + self.create_dm = async_to_raw_response_wrapper( + rooms.create_dm, + ) + self.create_group = async_to_raw_response_wrapper( + rooms.create_group, + ) + + +class RoomsResourceWithStreamingResponse: + def __init__(self, rooms: RoomsResource) -> None: + self._rooms = rooms + + self.create_dm = to_streamed_response_wrapper( + rooms.create_dm, + ) + self.create_group = to_streamed_response_wrapper( + rooms.create_group, + ) + + +class AsyncRoomsResourceWithStreamingResponse: + def __init__(self, rooms: AsyncRoomsResource) -> None: + self._rooms = rooms + + self.create_dm = async_to_streamed_response_wrapper( + rooms.create_dm, + ) + self.create_group = async_to_streamed_response_wrapper( + rooms.create_group, + ) diff --git a/src/beeper_desktop_api/resources/matrix/bridges/users.py b/src/beeper_desktop_api/resources/matrix/bridges/users.py new file mode 100644 index 0000000..541fc05 --- /dev/null +++ b/src/beeper_desktop_api/resources/matrix/bridges/users.py @@ -0,0 +1,304 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +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 +from ....types.matrix.bridges import user_search_params, user_resolve_params +from ....types.matrix.bridges.user_search_response import UserSearchResponse +from ....types.matrix.bridges.user_resolve_response import UserResolveResponse + +__all__ = ["UsersResource", "AsyncUsersResource"] + + +class UsersResource(SyncAPIResource): + """Matrix-compatible APIs for accounts and connected network bridges.""" + + @cached_property + def with_raw_response(self) -> UsersResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return UsersResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> UsersResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return UsersResourceWithStreamingResponse(self) + + def resolve( + self, + identifier: str, + *, + bridge_id: str, + login_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> UserResolveResponse: + """ + Resolve an identifier to a user on the remote network. + + Args: + login_id: An optional explicit login ID to do the action through. + + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + if not identifier: + raise ValueError(f"Expected a non-empty value for `identifier` but received {identifier!r}") + return self._get( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/resolve_identifier/{identifier}", + bridge_id=bridge_id, + identifier=identifier, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform({"login_id": login_id}, user_resolve_params.UserResolveParams), + ), + cast_to=UserResolveResponse, + ) + + def search( + self, + bridge_id: str, + *, + login_id: str | Omit = omit, + query: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> UserSearchResponse: + """ + Search for users on the remote network + + Args: + login_id: An optional explicit login ID to do the action through. + + query: The search query to send to the remote network + + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + return self._post( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/search_users", + bridge_id=bridge_id, + ), + body=maybe_transform({"query": query}, user_search_params.UserSearchParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform({"login_id": login_id}, user_search_params.UserSearchParams), + ), + cast_to=UserSearchResponse, + ) + + +class AsyncUsersResource(AsyncAPIResource): + """Matrix-compatible APIs for accounts and connected network bridges.""" + + @cached_property + def with_raw_response(self) -> AsyncUsersResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncUsersResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncUsersResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AsyncUsersResourceWithStreamingResponse(self) + + async def resolve( + self, + identifier: str, + *, + bridge_id: str, + login_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> UserResolveResponse: + """ + Resolve an identifier to a user on the remote network. + + Args: + login_id: An optional explicit login ID to do the action through. + + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + if not identifier: + raise ValueError(f"Expected a non-empty value for `identifier` but received {identifier!r}") + return await self._get( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/resolve_identifier/{identifier}", + bridge_id=bridge_id, + identifier=identifier, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform({"login_id": login_id}, user_resolve_params.UserResolveParams), + ), + cast_to=UserResolveResponse, + ) + + async def search( + self, + bridge_id: str, + *, + login_id: str | Omit = omit, + query: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> UserSearchResponse: + """ + Search for users on the remote network + + Args: + login_id: An optional explicit login ID to do the action through. + + query: The search query to send to the remote network + + 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 + """ + if not bridge_id: + raise ValueError(f"Expected a non-empty value for `bridge_id` but received {bridge_id!r}") + return await self._post( + path_template( + "/_matrix/client/unstable/com.beeper.bridge/{bridge_id}/_matrix/provision/v3/search_users", + bridge_id=bridge_id, + ), + body=await async_maybe_transform({"query": query}, user_search_params.UserSearchParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform({"login_id": login_id}, user_search_params.UserSearchParams), + ), + cast_to=UserSearchResponse, + ) + + +class UsersResourceWithRawResponse: + def __init__(self, users: UsersResource) -> None: + self._users = users + + self.resolve = to_raw_response_wrapper( + users.resolve, + ) + self.search = to_raw_response_wrapper( + users.search, + ) + + +class AsyncUsersResourceWithRawResponse: + def __init__(self, users: AsyncUsersResource) -> None: + self._users = users + + self.resolve = async_to_raw_response_wrapper( + users.resolve, + ) + self.search = async_to_raw_response_wrapper( + users.search, + ) + + +class UsersResourceWithStreamingResponse: + def __init__(self, users: UsersResource) -> None: + self._users = users + + self.resolve = to_streamed_response_wrapper( + users.resolve, + ) + self.search = to_streamed_response_wrapper( + users.search, + ) + + +class AsyncUsersResourceWithStreamingResponse: + def __init__(self, users: AsyncUsersResource) -> None: + self._users = users + + self.resolve = async_to_streamed_response_wrapper( + users.resolve, + ) + self.search = async_to_streamed_response_wrapper( + users.search, + ) diff --git a/src/beeper_desktop_api/resources/matrix/matrix.py b/src/beeper_desktop_api/resources/matrix/matrix.py new file mode 100644 index 0000000..8a494a3 --- /dev/null +++ b/src/beeper_desktop_api/resources/matrix/matrix.py @@ -0,0 +1,176 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from .rooms.rooms import ( + RoomsResource, + AsyncRoomsResource, + RoomsResourceWithRawResponse, + AsyncRoomsResourceWithRawResponse, + RoomsResourceWithStreamingResponse, + AsyncRoomsResourceWithStreamingResponse, +) +from .users.users import ( + UsersResource, + AsyncUsersResource, + UsersResourceWithRawResponse, + AsyncUsersResourceWithRawResponse, + UsersResourceWithStreamingResponse, + AsyncUsersResourceWithStreamingResponse, +) +from .bridges.bridges import ( + BridgesResource, + AsyncBridgesResource, + BridgesResourceWithRawResponse, + AsyncBridgesResourceWithRawResponse, + BridgesResourceWithStreamingResponse, + AsyncBridgesResourceWithStreamingResponse, +) + +__all__ = ["MatrixResource", "AsyncMatrixResource"] + + +class MatrixResource(SyncAPIResource): + """Matrix-compatible APIs for accounts, rooms, and connected network bridges.""" + + @cached_property + def users(self) -> UsersResource: + return UsersResource(self._client) + + @cached_property + def rooms(self) -> RoomsResource: + return RoomsResource(self._client) + + @cached_property + def bridges(self) -> BridgesResource: + """Matrix-compatible APIs for connected network bridges.""" + return BridgesResource(self._client) + + @cached_property + def with_raw_response(self) -> MatrixResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return MatrixResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> MatrixResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return MatrixResourceWithStreamingResponse(self) + + +class AsyncMatrixResource(AsyncAPIResource): + """Matrix-compatible APIs for accounts, rooms, and connected network bridges.""" + + @cached_property + def users(self) -> AsyncUsersResource: + return AsyncUsersResource(self._client) + + @cached_property + def rooms(self) -> AsyncRoomsResource: + return AsyncRoomsResource(self._client) + + @cached_property + def bridges(self) -> AsyncBridgesResource: + """Matrix-compatible APIs for connected network bridges.""" + return AsyncBridgesResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncMatrixResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncMatrixResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncMatrixResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AsyncMatrixResourceWithStreamingResponse(self) + + +class MatrixResourceWithRawResponse: + def __init__(self, matrix: MatrixResource) -> None: + self._matrix = matrix + + @cached_property + def users(self) -> UsersResourceWithRawResponse: + return UsersResourceWithRawResponse(self._matrix.users) + + @cached_property + def rooms(self) -> RoomsResourceWithRawResponse: + return RoomsResourceWithRawResponse(self._matrix.rooms) + + @cached_property + def bridges(self) -> BridgesResourceWithRawResponse: + """Matrix-compatible APIs for connected network bridges.""" + return BridgesResourceWithRawResponse(self._matrix.bridges) + + +class AsyncMatrixResourceWithRawResponse: + def __init__(self, matrix: AsyncMatrixResource) -> None: + self._matrix = matrix + + @cached_property + def users(self) -> AsyncUsersResourceWithRawResponse: + return AsyncUsersResourceWithRawResponse(self._matrix.users) + + @cached_property + def rooms(self) -> AsyncRoomsResourceWithRawResponse: + return AsyncRoomsResourceWithRawResponse(self._matrix.rooms) + + @cached_property + def bridges(self) -> AsyncBridgesResourceWithRawResponse: + """Matrix-compatible APIs for connected network bridges.""" + return AsyncBridgesResourceWithRawResponse(self._matrix.bridges) + + +class MatrixResourceWithStreamingResponse: + def __init__(self, matrix: MatrixResource) -> None: + self._matrix = matrix + + @cached_property + def users(self) -> UsersResourceWithStreamingResponse: + return UsersResourceWithStreamingResponse(self._matrix.users) + + @cached_property + def rooms(self) -> RoomsResourceWithStreamingResponse: + return RoomsResourceWithStreamingResponse(self._matrix.rooms) + + @cached_property + def bridges(self) -> BridgesResourceWithStreamingResponse: + """Matrix-compatible APIs for connected network bridges.""" + return BridgesResourceWithStreamingResponse(self._matrix.bridges) + + +class AsyncMatrixResourceWithStreamingResponse: + def __init__(self, matrix: AsyncMatrixResource) -> None: + self._matrix = matrix + + @cached_property + def users(self) -> AsyncUsersResourceWithStreamingResponse: + return AsyncUsersResourceWithStreamingResponse(self._matrix.users) + + @cached_property + def rooms(self) -> AsyncRoomsResourceWithStreamingResponse: + return AsyncRoomsResourceWithStreamingResponse(self._matrix.rooms) + + @cached_property + def bridges(self) -> AsyncBridgesResourceWithStreamingResponse: + """Matrix-compatible APIs for connected network bridges.""" + return AsyncBridgesResourceWithStreamingResponse(self._matrix.bridges) diff --git a/src/beeper_desktop_api/resources/matrix/rooms/__init__.py b/src/beeper_desktop_api/resources/matrix/rooms/__init__.py new file mode 100644 index 0000000..443fc1b --- /dev/null +++ b/src/beeper_desktop_api/resources/matrix/rooms/__init__.py @@ -0,0 +1,61 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .rooms import ( + RoomsResource, + AsyncRoomsResource, + RoomsResourceWithRawResponse, + AsyncRoomsResourceWithRawResponse, + RoomsResourceWithStreamingResponse, + AsyncRoomsResourceWithStreamingResponse, +) +from .state import ( + StateResource, + AsyncStateResource, + StateResourceWithRawResponse, + AsyncStateResourceWithRawResponse, + StateResourceWithStreamingResponse, + AsyncStateResourceWithStreamingResponse, +) +from .events import ( + EventsResource, + AsyncEventsResource, + EventsResourceWithRawResponse, + AsyncEventsResourceWithRawResponse, + EventsResourceWithStreamingResponse, + AsyncEventsResourceWithStreamingResponse, +) +from .account_data import ( + AccountDataResource, + AsyncAccountDataResource, + AccountDataResourceWithRawResponse, + AsyncAccountDataResourceWithRawResponse, + AccountDataResourceWithStreamingResponse, + AsyncAccountDataResourceWithStreamingResponse, +) + +__all__ = [ + "AccountDataResource", + "AsyncAccountDataResource", + "AccountDataResourceWithRawResponse", + "AsyncAccountDataResourceWithRawResponse", + "AccountDataResourceWithStreamingResponse", + "AsyncAccountDataResourceWithStreamingResponse", + "StateResource", + "AsyncStateResource", + "StateResourceWithRawResponse", + "AsyncStateResourceWithRawResponse", + "StateResourceWithStreamingResponse", + "AsyncStateResourceWithStreamingResponse", + "EventsResource", + "AsyncEventsResource", + "EventsResourceWithRawResponse", + "AsyncEventsResourceWithRawResponse", + "EventsResourceWithStreamingResponse", + "AsyncEventsResourceWithStreamingResponse", + "RoomsResource", + "AsyncRoomsResource", + "RoomsResourceWithRawResponse", + "AsyncRoomsResourceWithRawResponse", + "RoomsResourceWithStreamingResponse", + "AsyncRoomsResourceWithStreamingResponse", +] diff --git a/src/beeper_desktop_api/resources/matrix/rooms/account_data.py b/src/beeper_desktop_api/resources/matrix/rooms/account_data.py new file mode 100644 index 0000000..967c27c --- /dev/null +++ b/src/beeper_desktop_api/resources/matrix/rooms/account_data.py @@ -0,0 +1,302 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ...._types import Body, Query, Headers, NotGiven, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +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 +from ....types.matrix.rooms import account_data_update_params + +__all__ = ["AccountDataResource", "AsyncAccountDataResource"] + + +class AccountDataResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> AccountDataResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AccountDataResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AccountDataResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AccountDataResourceWithStreamingResponse(self) + + def retrieve( + self, + type: str, + *, + user_id: str, + room_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """Get some account data for the client on a given room. + + This config is only + visible to the user that set the account data. + + Args: + 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 + """ + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + if not room_id: + raise ValueError(f"Expected a non-empty value for `room_id` but received {room_id!r}") + if not type: + raise ValueError(f"Expected a non-empty value for `type` but received {type!r}") + return self._get( + path_template( + "/_matrix/client/v3/user/{user_id}/rooms/{room_id}/account_data/{type}", + user_id=user_id, + room_id=room_id, + type=type, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=object, + ) + + def update( + self, + type: str, + *, + user_id: str, + room_id: str, + body: object, + # 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: + """Set some account data for the client on a given room. + + This config is only + visible to the user that set the account data. The config will be delivered to + clients in the per-room entries via + [/sync](https://spec.matrix.org/v1.18/client-server-api/#get_matrixclientv3sync). + + Args: + 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 + """ + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + if not room_id: + raise ValueError(f"Expected a non-empty value for `room_id` but received {room_id!r}") + if not type: + raise ValueError(f"Expected a non-empty value for `type` but received {type!r}") + return self._put( + path_template( + "/_matrix/client/v3/user/{user_id}/rooms/{room_id}/account_data/{type}", + user_id=user_id, + room_id=room_id, + type=type, + ), + body=maybe_transform(body, account_data_update_params.AccountDataUpdateParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=object, + ) + + +class AsyncAccountDataResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncAccountDataResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncAccountDataResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncAccountDataResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AsyncAccountDataResourceWithStreamingResponse(self) + + async def retrieve( + self, + type: str, + *, + user_id: str, + room_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """Get some account data for the client on a given room. + + This config is only + visible to the user that set the account data. + + Args: + 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 + """ + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + if not room_id: + raise ValueError(f"Expected a non-empty value for `room_id` but received {room_id!r}") + if not type: + raise ValueError(f"Expected a non-empty value for `type` but received {type!r}") + return await self._get( + path_template( + "/_matrix/client/v3/user/{user_id}/rooms/{room_id}/account_data/{type}", + user_id=user_id, + room_id=room_id, + type=type, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=object, + ) + + async def update( + self, + type: str, + *, + user_id: str, + room_id: str, + body: object, + # 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: + """Set some account data for the client on a given room. + + This config is only + visible to the user that set the account data. The config will be delivered to + clients in the per-room entries via + [/sync](https://spec.matrix.org/v1.18/client-server-api/#get_matrixclientv3sync). + + Args: + 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 + """ + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + if not room_id: + raise ValueError(f"Expected a non-empty value for `room_id` but received {room_id!r}") + if not type: + raise ValueError(f"Expected a non-empty value for `type` but received {type!r}") + return await self._put( + path_template( + "/_matrix/client/v3/user/{user_id}/rooms/{room_id}/account_data/{type}", + user_id=user_id, + room_id=room_id, + type=type, + ), + body=await async_maybe_transform(body, account_data_update_params.AccountDataUpdateParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=object, + ) + + +class AccountDataResourceWithRawResponse: + def __init__(self, account_data: AccountDataResource) -> None: + self._account_data = account_data + + self.retrieve = to_raw_response_wrapper( + account_data.retrieve, + ) + self.update = to_raw_response_wrapper( + account_data.update, + ) + + +class AsyncAccountDataResourceWithRawResponse: + def __init__(self, account_data: AsyncAccountDataResource) -> None: + self._account_data = account_data + + self.retrieve = async_to_raw_response_wrapper( + account_data.retrieve, + ) + self.update = async_to_raw_response_wrapper( + account_data.update, + ) + + +class AccountDataResourceWithStreamingResponse: + def __init__(self, account_data: AccountDataResource) -> None: + self._account_data = account_data + + self.retrieve = to_streamed_response_wrapper( + account_data.retrieve, + ) + self.update = to_streamed_response_wrapper( + account_data.update, + ) + + +class AsyncAccountDataResourceWithStreamingResponse: + def __init__(self, account_data: AsyncAccountDataResource) -> None: + self._account_data = account_data + + self.retrieve = async_to_streamed_response_wrapper( + account_data.retrieve, + ) + self.update = async_to_streamed_response_wrapper( + account_data.update, + ) diff --git a/src/beeper_desktop_api/resources/matrix/rooms/events.py b/src/beeper_desktop_api/resources/matrix/rooms/events.py new file mode 100644 index 0000000..c7dc565 --- /dev/null +++ b/src/beeper_desktop_api/resources/matrix/rooms/events.py @@ -0,0 +1,174 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ...._types import Body, Query, Headers, NotGiven, not_given +from ...._utils import path_template +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 +from ....types.matrix.rooms.event_retrieve_response import EventRetrieveResponse + +__all__ = ["EventsResource", "AsyncEventsResource"] + + +class EventsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> EventsResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return EventsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> EventsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return EventsResourceWithStreamingResponse(self) + + def retrieve( + self, + event_id: str, + *, + room_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> EventRetrieveResponse: + """Get a single event based on `roomId/eventId`. + + You must have permission to + retrieve this event e.g. by being a member in the room for this event. + + Args: + 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 + """ + if not room_id: + raise ValueError(f"Expected a non-empty value for `room_id` but received {room_id!r}") + if not event_id: + raise ValueError(f"Expected a non-empty value for `event_id` but received {event_id!r}") + return self._get( + path_template("/_matrix/client/v3/rooms/{room_id}/event/{event_id}", room_id=room_id, event_id=event_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=EventRetrieveResponse, + ) + + +class AsyncEventsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncEventsResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncEventsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncEventsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AsyncEventsResourceWithStreamingResponse(self) + + async def retrieve( + self, + event_id: str, + *, + room_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> EventRetrieveResponse: + """Get a single event based on `roomId/eventId`. + + You must have permission to + retrieve this event e.g. by being a member in the room for this event. + + Args: + 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 + """ + if not room_id: + raise ValueError(f"Expected a non-empty value for `room_id` but received {room_id!r}") + if not event_id: + raise ValueError(f"Expected a non-empty value for `event_id` but received {event_id!r}") + return await self._get( + path_template("/_matrix/client/v3/rooms/{room_id}/event/{event_id}", room_id=room_id, event_id=event_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=EventRetrieveResponse, + ) + + +class EventsResourceWithRawResponse: + def __init__(self, events: EventsResource) -> None: + self._events = events + + self.retrieve = to_raw_response_wrapper( + events.retrieve, + ) + + +class AsyncEventsResourceWithRawResponse: + def __init__(self, events: AsyncEventsResource) -> None: + self._events = events + + self.retrieve = async_to_raw_response_wrapper( + events.retrieve, + ) + + +class EventsResourceWithStreamingResponse: + def __init__(self, events: EventsResource) -> None: + self._events = events + + self.retrieve = to_streamed_response_wrapper( + events.retrieve, + ) + + +class AsyncEventsResourceWithStreamingResponse: + def __init__(self, events: AsyncEventsResource) -> None: + self._events = events + + self.retrieve = async_to_streamed_response_wrapper( + events.retrieve, + ) diff --git a/src/beeper_desktop_api/resources/matrix/rooms/rooms.py b/src/beeper_desktop_api/resources/matrix/rooms/rooms.py new file mode 100644 index 0000000..2686e32 --- /dev/null +++ b/src/beeper_desktop_api/resources/matrix/rooms/rooms.py @@ -0,0 +1,845 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable +from typing_extensions import Literal + +import httpx + +from .state import ( + StateResource, + AsyncStateResource, + StateResourceWithRawResponse, + AsyncStateResourceWithRawResponse, + StateResourceWithStreamingResponse, + AsyncStateResourceWithStreamingResponse, +) +from .events import ( + EventsResource, + AsyncEventsResource, + EventsResourceWithRawResponse, + AsyncEventsResourceWithRawResponse, + EventsResourceWithStreamingResponse, + AsyncEventsResourceWithStreamingResponse, +) +from ...._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +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 .account_data import ( + AccountDataResource, + AsyncAccountDataResource, + AccountDataResourceWithRawResponse, + AsyncAccountDataResourceWithRawResponse, + AccountDataResourceWithStreamingResponse, + AsyncAccountDataResourceWithStreamingResponse, +) +from ...._base_client import make_request_options +from ....types.matrix import room_join_params, room_leave_params, room_create_params +from ....types.matrix.room_join_response import RoomJoinResponse +from ....types.matrix.room_create_response import RoomCreateResponse + +__all__ = ["RoomsResource", "AsyncRoomsResource"] + + +class RoomsResource(SyncAPIResource): + @cached_property + def account_data(self) -> AccountDataResource: + return AccountDataResource(self._client) + + @cached_property + def state(self) -> StateResource: + return StateResource(self._client) + + @cached_property + def events(self) -> EventsResource: + return EventsResource(self._client) + + @cached_property + def with_raw_response(self) -> RoomsResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return RoomsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> RoomsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return RoomsResourceWithStreamingResponse(self) + + def create( + self, + *, + creation_content: object | Omit = omit, + initial_state: Iterable[room_create_params.InitialState] | Omit = omit, + invite: SequenceNotStr[str] | Omit = omit, + invite_3pid: Iterable[room_create_params.Invite3pid] | Omit = omit, + is_direct: bool | Omit = omit, + name: str | Omit = omit, + power_level_content_override: object | Omit = omit, + preset: Literal["private_chat", "public_chat", "trusted_private_chat"] | Omit = omit, + room_alias_name: str | Omit = omit, + room_version: str | Omit = omit, + topic: str | Omit = omit, + visibility: Literal["public", "private"] | 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RoomCreateResponse: + """ + Create a new room with various configuration options. + + The server MUST apply the normal state resolution rules when creating the new + room, including checking power levels for each event. It MUST apply the events + implied by the request in the following order: + + 1. The `m.room.create` event itself. Must be the first event in the room. + + 2. An `m.room.member` event for the creator to join the room. This is needed so + the remaining events can be sent. + + 3. A default `m.room.power_levels` event. Overridden by the + `power_level_content_override` parameter. + + In [room versions](https://spec.matrix.org/v1.18/rooms) 1 through 11, the + room creator (and not other members) will be given permission to send state + events. + + In room versions 12 and later, the room creator is given infinite power level + and cannot be specified in the `users` field of `m.room.power_levels`, so is + not listed explicitly. + + **Note**: For `trusted_private_chat`, the users specified in the `invite` + parameter SHOULD also be appended to `additional_creators` by the server, per + the `creation_content` parameter. + + If the room's version is 12 or higher, the power level for sending + `m.room.tombstone` events MUST explicitly be higher than `state_default`. For + example, set to 150 instead of 100. + + 4. An `m.room.canonical_alias` event if `room_alias_name` is given. + + 5. Events set by the `preset`. Currently these are the `m.room.join_rules`, + `m.room.history_visibility`, and `m.room.guest_access` state events. + + 6. Events listed in `initial_state`, in the order that they are listed. + + 7. Events implied by `name` and `topic` (`m.room.name` and `m.room.topic` state + events). + + 8. Invite events implied by `invite` and `invite_3pid` (`m.room.member` with + `membership: invite` and `m.room.third_party_invite`). + + The available presets do the following with respect to room state: + + | Preset | `join_rules` | `history_visibility` | `guest_access` | Other | + | ---------------------- | ------------ | -------------------- | -------------- | ---------------------------------------------------------------- | + | `private_chat` | `invite` | `shared` | `can_join` | | + | `trusted_private_chat` | `invite` | `shared` | `can_join` | All invitees are given the same power level as the room creator. | + | `public_chat` | `public` | `shared` | `forbidden` | | + + The server will create a `m.room.create` event in the room with the requesting + user as the creator, alongside other keys provided in the `creation_content` or + implied by behaviour of `creation_content`. + + Args: + creation_content: Extra keys, such as `m.federate`, to be added to the content of the + [`m.room.create`](https://spec.matrix.org/v1.18/client-server-api/#mroomcreate) + event. + + The server will overwrite the following keys: `creator`, `room_version`. Future + versions of the specification may allow the server to overwrite other keys. + + When using the `trusted_private_chat` preset, the server SHOULD combine + `additional_creators` specified here and the `invite` array into the eventual + `m.room.create` event's `additional_creators`, deduplicating between the two + parameters. + + initial_state: A list of state events to set in the new room. This allows the user to override + the default state events set in the new room. The expected format of the state + events are an object with type, state_key and content keys set. + + Takes precedence over events set by `preset`, but gets overridden by `name` and + `topic` keys. + + invite: A list of user IDs to invite to the room. This will tell the server to invite + everyone in the list to the newly created room. + + invite_3pid: A list of objects representing third-party IDs to invite into the room. + + is_direct: This flag makes the server set the `is_direct` flag on the `m.room.member` + events sent to the users in `invite` and `invite_3pid`. See + [Direct Messaging](https://spec.matrix.org/v1.18/client-server-api/#direct-messaging) + for more information. + + name: If this is included, an + [`m.room.name`](https://spec.matrix.org/v1.18/client-server-api/#mroomname) + event will be sent into the room to indicate the name for the room. This + overwrites any + [`m.room.name`](https://spec.matrix.org/v1.18/client-server-api/#mroomname) + event in `initial_state`. + + power_level_content_override: The power level content to override in the default power level event. This + object is applied on top of the generated + [`m.room.power_levels`](https://spec.matrix.org/v1.18/client-server-api/#mroompower_levels) + event content prior to it being sent to the room. Defaults to overriding + nothing. + + preset: Convenience parameter for setting various default state events based on a + preset. + + If unspecified, the server should use the `visibility` to determine which preset + to use. A visibility of `public` equates to a preset of `public_chat` and + `private` visibility equates to a preset of `private_chat`. + + room_alias_name: The desired room alias **local part**. If this is included, a room alias will be + created and mapped to the newly created room. The alias will belong on the + _same_ homeserver which created the room. For example, if this was set to "foo" + and sent to the homeserver "example.com" the complete room alias would be + `#foo:example.com`. + + The complete room alias will become the canonical alias for the room and an + `m.room.canonical_alias` event will be sent into the room. + + room_version: The room version to set for the room. If not provided, the homeserver is to use + its configured default. If provided, the homeserver will return a 400 error with + the errcode `M_UNSUPPORTED_ROOM_VERSION` if it does not support the room + version. + + topic: If this is included, an + [`m.room.topic`](https://spec.matrix.org/v1.18/client-server-api/#mroomtopic) + event with a `text/plain` mimetype will be sent into the room to indicate the + topic for the room. This overwrites any + [`m.room.topic`](https://spec.matrix.org/v1.18/client-server-api/#mroomtopic) + event in `initial_state`. + + visibility: The room's visibility in the server's + [published room directory](https://spec.matrix.org/v1.18/client-server-api#published-room-directory). + Defaults to `private`. + + 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 + """ + return self._post( + "/_matrix/client/v3/createRoom", + body=maybe_transform( + { + "creation_content": creation_content, + "initial_state": initial_state, + "invite": invite, + "invite_3pid": invite_3pid, + "is_direct": is_direct, + "name": name, + "power_level_content_override": power_level_content_override, + "preset": preset, + "room_alias_name": room_alias_name, + "room_version": room_version, + "topic": topic, + "visibility": visibility, + }, + room_create_params.RoomCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=RoomCreateResponse, + ) + + def join( + self, + room_id_or_alias: str, + *, + via: SequenceNotStr[str] | Omit = omit, + reason: str | Omit = omit, + third_party_signed: room_join_params.ThirdPartySigned | 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RoomJoinResponse: + """ + _Note that this API takes either a room ID or alias, unlike_ + `/rooms/{roomId}/join`. + + This API starts a user's participation in a particular room, if that user is + allowed to participate in that room. After this call, the client is allowed to + see all current state events in the room, and all subsequent events associated + with the room until the user leaves the room. + + After a user has joined a room, the room will appear as an entry in the response + of the + [`/initialSync`](https://spec.matrix.org/v1.18/client-server-api/#get_matrixclientv3initialsync) + and + [`/sync`](https://spec.matrix.org/v1.18/client-server-api/#get_matrixclientv3sync) + APIs. + + Args: + via: The servers to attempt to join the room through. One of the servers must be + participating in the room. + + reason: Optional reason to be included as the `reason` on the subsequent membership + event. + + third_party_signed: A signature of an `m.third_party_invite` token to prove that this user owns a + third-party identity which has been invited to the room. + + 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 + """ + if not room_id_or_alias: + raise ValueError(f"Expected a non-empty value for `room_id_or_alias` but received {room_id_or_alias!r}") + return self._post( + path_template("/_matrix/client/v3/join/{room_id_or_alias}", room_id_or_alias=room_id_or_alias), + body=maybe_transform( + { + "reason": reason, + "third_party_signed": third_party_signed, + }, + room_join_params.RoomJoinParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform({"via": via}, room_join_params.RoomJoinParams), + ), + cast_to=RoomJoinResponse, + ) + + def leave( + self, + room_id: str, + *, + reason: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """ + This API stops a user participating in a particular room. + + If the user was already in the room, they will no longer be able to see new + events in the room. If the room requires an invite to join, they will need to be + re-invited before they can re-join. + + If the user was invited to the room, but had not joined, this call serves to + reject the invite. + + Servers MAY additionally forget the room when this endpoint is called – just as + if the user had also invoked + [`/forget`](https://spec.matrix.org/v1.18/client-server-api/#post_matrixclientv3roomsroomidforget). + Servers that do this, MUST inform clients about this behavior using the + [`m.forget_forced_upon_leave`](https://spec.matrix.org/v1.18/client-server-api/#mforget_forced_upon_leave-capability) + capability. + + If the server doesn't automatically forget the room, the user will still be + allowed to retrieve history from the room which they were previously allowed to + see. + + Args: + reason: Optional reason to be included as the `reason` on the subsequent membership + event. + + 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 + """ + if not room_id: + raise ValueError(f"Expected a non-empty value for `room_id` but received {room_id!r}") + return self._post( + path_template("/_matrix/client/v3/rooms/{room_id}/leave", room_id=room_id), + body=maybe_transform({"reason": reason}, room_leave_params.RoomLeaveParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=object, + ) + + +class AsyncRoomsResource(AsyncAPIResource): + @cached_property + def account_data(self) -> AsyncAccountDataResource: + return AsyncAccountDataResource(self._client) + + @cached_property + def state(self) -> AsyncStateResource: + return AsyncStateResource(self._client) + + @cached_property + def events(self) -> AsyncEventsResource: + return AsyncEventsResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncRoomsResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncRoomsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncRoomsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AsyncRoomsResourceWithStreamingResponse(self) + + async def create( + self, + *, + creation_content: object | Omit = omit, + initial_state: Iterable[room_create_params.InitialState] | Omit = omit, + invite: SequenceNotStr[str] | Omit = omit, + invite_3pid: Iterable[room_create_params.Invite3pid] | Omit = omit, + is_direct: bool | Omit = omit, + name: str | Omit = omit, + power_level_content_override: object | Omit = omit, + preset: Literal["private_chat", "public_chat", "trusted_private_chat"] | Omit = omit, + room_alias_name: str | Omit = omit, + room_version: str | Omit = omit, + topic: str | Omit = omit, + visibility: Literal["public", "private"] | 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RoomCreateResponse: + """ + Create a new room with various configuration options. + + The server MUST apply the normal state resolution rules when creating the new + room, including checking power levels for each event. It MUST apply the events + implied by the request in the following order: + + 1. The `m.room.create` event itself. Must be the first event in the room. + + 2. An `m.room.member` event for the creator to join the room. This is needed so + the remaining events can be sent. + + 3. A default `m.room.power_levels` event. Overridden by the + `power_level_content_override` parameter. + + In [room versions](https://spec.matrix.org/v1.18/rooms) 1 through 11, the + room creator (and not other members) will be given permission to send state + events. + + In room versions 12 and later, the room creator is given infinite power level + and cannot be specified in the `users` field of `m.room.power_levels`, so is + not listed explicitly. + + **Note**: For `trusted_private_chat`, the users specified in the `invite` + parameter SHOULD also be appended to `additional_creators` by the server, per + the `creation_content` parameter. + + If the room's version is 12 or higher, the power level for sending + `m.room.tombstone` events MUST explicitly be higher than `state_default`. For + example, set to 150 instead of 100. + + 4. An `m.room.canonical_alias` event if `room_alias_name` is given. + + 5. Events set by the `preset`. Currently these are the `m.room.join_rules`, + `m.room.history_visibility`, and `m.room.guest_access` state events. + + 6. Events listed in `initial_state`, in the order that they are listed. + + 7. Events implied by `name` and `topic` (`m.room.name` and `m.room.topic` state + events). + + 8. Invite events implied by `invite` and `invite_3pid` (`m.room.member` with + `membership: invite` and `m.room.third_party_invite`). + + The available presets do the following with respect to room state: + + | Preset | `join_rules` | `history_visibility` | `guest_access` | Other | + | ---------------------- | ------------ | -------------------- | -------------- | ---------------------------------------------------------------- | + | `private_chat` | `invite` | `shared` | `can_join` | | + | `trusted_private_chat` | `invite` | `shared` | `can_join` | All invitees are given the same power level as the room creator. | + | `public_chat` | `public` | `shared` | `forbidden` | | + + The server will create a `m.room.create` event in the room with the requesting + user as the creator, alongside other keys provided in the `creation_content` or + implied by behaviour of `creation_content`. + + Args: + creation_content: Extra keys, such as `m.federate`, to be added to the content of the + [`m.room.create`](https://spec.matrix.org/v1.18/client-server-api/#mroomcreate) + event. + + The server will overwrite the following keys: `creator`, `room_version`. Future + versions of the specification may allow the server to overwrite other keys. + + When using the `trusted_private_chat` preset, the server SHOULD combine + `additional_creators` specified here and the `invite` array into the eventual + `m.room.create` event's `additional_creators`, deduplicating between the two + parameters. + + initial_state: A list of state events to set in the new room. This allows the user to override + the default state events set in the new room. The expected format of the state + events are an object with type, state_key and content keys set. + + Takes precedence over events set by `preset`, but gets overridden by `name` and + `topic` keys. + + invite: A list of user IDs to invite to the room. This will tell the server to invite + everyone in the list to the newly created room. + + invite_3pid: A list of objects representing third-party IDs to invite into the room. + + is_direct: This flag makes the server set the `is_direct` flag on the `m.room.member` + events sent to the users in `invite` and `invite_3pid`. See + [Direct Messaging](https://spec.matrix.org/v1.18/client-server-api/#direct-messaging) + for more information. + + name: If this is included, an + [`m.room.name`](https://spec.matrix.org/v1.18/client-server-api/#mroomname) + event will be sent into the room to indicate the name for the room. This + overwrites any + [`m.room.name`](https://spec.matrix.org/v1.18/client-server-api/#mroomname) + event in `initial_state`. + + power_level_content_override: The power level content to override in the default power level event. This + object is applied on top of the generated + [`m.room.power_levels`](https://spec.matrix.org/v1.18/client-server-api/#mroompower_levels) + event content prior to it being sent to the room. Defaults to overriding + nothing. + + preset: Convenience parameter for setting various default state events based on a + preset. + + If unspecified, the server should use the `visibility` to determine which preset + to use. A visibility of `public` equates to a preset of `public_chat` and + `private` visibility equates to a preset of `private_chat`. + + room_alias_name: The desired room alias **local part**. If this is included, a room alias will be + created and mapped to the newly created room. The alias will belong on the + _same_ homeserver which created the room. For example, if this was set to "foo" + and sent to the homeserver "example.com" the complete room alias would be + `#foo:example.com`. + + The complete room alias will become the canonical alias for the room and an + `m.room.canonical_alias` event will be sent into the room. + + room_version: The room version to set for the room. If not provided, the homeserver is to use + its configured default. If provided, the homeserver will return a 400 error with + the errcode `M_UNSUPPORTED_ROOM_VERSION` if it does not support the room + version. + + topic: If this is included, an + [`m.room.topic`](https://spec.matrix.org/v1.18/client-server-api/#mroomtopic) + event with a `text/plain` mimetype will be sent into the room to indicate the + topic for the room. This overwrites any + [`m.room.topic`](https://spec.matrix.org/v1.18/client-server-api/#mroomtopic) + event in `initial_state`. + + visibility: The room's visibility in the server's + [published room directory](https://spec.matrix.org/v1.18/client-server-api#published-room-directory). + Defaults to `private`. + + 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 + """ + return await self._post( + "/_matrix/client/v3/createRoom", + body=await async_maybe_transform( + { + "creation_content": creation_content, + "initial_state": initial_state, + "invite": invite, + "invite_3pid": invite_3pid, + "is_direct": is_direct, + "name": name, + "power_level_content_override": power_level_content_override, + "preset": preset, + "room_alias_name": room_alias_name, + "room_version": room_version, + "topic": topic, + "visibility": visibility, + }, + room_create_params.RoomCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=RoomCreateResponse, + ) + + async def join( + self, + room_id_or_alias: str, + *, + via: SequenceNotStr[str] | Omit = omit, + reason: str | Omit = omit, + third_party_signed: room_join_params.ThirdPartySigned | 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RoomJoinResponse: + """ + _Note that this API takes either a room ID or alias, unlike_ + `/rooms/{roomId}/join`. + + This API starts a user's participation in a particular room, if that user is + allowed to participate in that room. After this call, the client is allowed to + see all current state events in the room, and all subsequent events associated + with the room until the user leaves the room. + + After a user has joined a room, the room will appear as an entry in the response + of the + [`/initialSync`](https://spec.matrix.org/v1.18/client-server-api/#get_matrixclientv3initialsync) + and + [`/sync`](https://spec.matrix.org/v1.18/client-server-api/#get_matrixclientv3sync) + APIs. + + Args: + via: The servers to attempt to join the room through. One of the servers must be + participating in the room. + + reason: Optional reason to be included as the `reason` on the subsequent membership + event. + + third_party_signed: A signature of an `m.third_party_invite` token to prove that this user owns a + third-party identity which has been invited to the room. + + 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 + """ + if not room_id_or_alias: + raise ValueError(f"Expected a non-empty value for `room_id_or_alias` but received {room_id_or_alias!r}") + return await self._post( + path_template("/_matrix/client/v3/join/{room_id_or_alias}", room_id_or_alias=room_id_or_alias), + body=await async_maybe_transform( + { + "reason": reason, + "third_party_signed": third_party_signed, + }, + room_join_params.RoomJoinParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform({"via": via}, room_join_params.RoomJoinParams), + ), + cast_to=RoomJoinResponse, + ) + + async def leave( + self, + room_id: str, + *, + reason: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """ + This API stops a user participating in a particular room. + + If the user was already in the room, they will no longer be able to see new + events in the room. If the room requires an invite to join, they will need to be + re-invited before they can re-join. + + If the user was invited to the room, but had not joined, this call serves to + reject the invite. + + Servers MAY additionally forget the room when this endpoint is called – just as + if the user had also invoked + [`/forget`](https://spec.matrix.org/v1.18/client-server-api/#post_matrixclientv3roomsroomidforget). + Servers that do this, MUST inform clients about this behavior using the + [`m.forget_forced_upon_leave`](https://spec.matrix.org/v1.18/client-server-api/#mforget_forced_upon_leave-capability) + capability. + + If the server doesn't automatically forget the room, the user will still be + allowed to retrieve history from the room which they were previously allowed to + see. + + Args: + reason: Optional reason to be included as the `reason` on the subsequent membership + event. + + 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 + """ + if not room_id: + raise ValueError(f"Expected a non-empty value for `room_id` but received {room_id!r}") + return await self._post( + path_template("/_matrix/client/v3/rooms/{room_id}/leave", room_id=room_id), + body=await async_maybe_transform({"reason": reason}, room_leave_params.RoomLeaveParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=object, + ) + + +class RoomsResourceWithRawResponse: + def __init__(self, rooms: RoomsResource) -> None: + self._rooms = rooms + + self.create = to_raw_response_wrapper( + rooms.create, + ) + self.join = to_raw_response_wrapper( + rooms.join, + ) + self.leave = to_raw_response_wrapper( + rooms.leave, + ) + + @cached_property + def account_data(self) -> AccountDataResourceWithRawResponse: + return AccountDataResourceWithRawResponse(self._rooms.account_data) + + @cached_property + def state(self) -> StateResourceWithRawResponse: + return StateResourceWithRawResponse(self._rooms.state) + + @cached_property + def events(self) -> EventsResourceWithRawResponse: + return EventsResourceWithRawResponse(self._rooms.events) + + +class AsyncRoomsResourceWithRawResponse: + def __init__(self, rooms: AsyncRoomsResource) -> None: + self._rooms = rooms + + self.create = async_to_raw_response_wrapper( + rooms.create, + ) + self.join = async_to_raw_response_wrapper( + rooms.join, + ) + self.leave = async_to_raw_response_wrapper( + rooms.leave, + ) + + @cached_property + def account_data(self) -> AsyncAccountDataResourceWithRawResponse: + return AsyncAccountDataResourceWithRawResponse(self._rooms.account_data) + + @cached_property + def state(self) -> AsyncStateResourceWithRawResponse: + return AsyncStateResourceWithRawResponse(self._rooms.state) + + @cached_property + def events(self) -> AsyncEventsResourceWithRawResponse: + return AsyncEventsResourceWithRawResponse(self._rooms.events) + + +class RoomsResourceWithStreamingResponse: + def __init__(self, rooms: RoomsResource) -> None: + self._rooms = rooms + + self.create = to_streamed_response_wrapper( + rooms.create, + ) + self.join = to_streamed_response_wrapper( + rooms.join, + ) + self.leave = to_streamed_response_wrapper( + rooms.leave, + ) + + @cached_property + def account_data(self) -> AccountDataResourceWithStreamingResponse: + return AccountDataResourceWithStreamingResponse(self._rooms.account_data) + + @cached_property + def state(self) -> StateResourceWithStreamingResponse: + return StateResourceWithStreamingResponse(self._rooms.state) + + @cached_property + def events(self) -> EventsResourceWithStreamingResponse: + return EventsResourceWithStreamingResponse(self._rooms.events) + + +class AsyncRoomsResourceWithStreamingResponse: + def __init__(self, rooms: AsyncRoomsResource) -> None: + self._rooms = rooms + + self.create = async_to_streamed_response_wrapper( + rooms.create, + ) + self.join = async_to_streamed_response_wrapper( + rooms.join, + ) + self.leave = async_to_streamed_response_wrapper( + rooms.leave, + ) + + @cached_property + def account_data(self) -> AsyncAccountDataResourceWithStreamingResponse: + return AsyncAccountDataResourceWithStreamingResponse(self._rooms.account_data) + + @cached_property + def state(self) -> AsyncStateResourceWithStreamingResponse: + return AsyncStateResourceWithStreamingResponse(self._rooms.state) + + @cached_property + def events(self) -> AsyncEventsResourceWithStreamingResponse: + return AsyncEventsResourceWithStreamingResponse(self._rooms.events) diff --git a/src/beeper_desktop_api/resources/matrix/rooms/state.py b/src/beeper_desktop_api/resources/matrix/rooms/state.py new file mode 100644 index 0000000..dc7f15f --- /dev/null +++ b/src/beeper_desktop_api/resources/matrix/rooms/state.py @@ -0,0 +1,294 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal + +import httpx + +from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +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 +from ....types.matrix.rooms import state_retrieve_params +from ....types.matrix.rooms.state_list_response import StateListResponse +from ....types.matrix.rooms.state_retrieve_response import StateRetrieveResponse + +__all__ = ["StateResource", "AsyncStateResource"] + + +class StateResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> StateResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return StateResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> StateResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return StateResourceWithStreamingResponse(self) + + def retrieve( + self, + state_key: str, + *, + room_id: str, + event_type: str, + format: Literal["content", "event"] | 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> StateRetrieveResponse: + """Looks up the contents of a state event in a room. + + If the user is joined to the + room then the state is taken from the current state of the room. If the user has + left the room then the state is taken from the state of the room when they left. + + Args: + format: The format to use for the returned data. `content` (the default) will return + only the content of the state event. `event` will return the entire event in the + usual format suitable for clients, including fields like event ID, sender and + timestamp. + + 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 + """ + if not room_id: + raise ValueError(f"Expected a non-empty value for `room_id` but received {room_id!r}") + if not event_type: + raise ValueError(f"Expected a non-empty value for `event_type` but received {event_type!r}") + if not state_key: + raise ValueError(f"Expected a non-empty value for `state_key` but received {state_key!r}") + return self._get( + path_template( + "/_matrix/client/v3/rooms/{room_id}/state/{event_type}/{state_key}", + room_id=room_id, + event_type=event_type, + state_key=state_key, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform({"format": format}, state_retrieve_params.StateRetrieveParams), + ), + cast_to=StateRetrieveResponse, + ) + + def list( + self, + room_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> StateListResponse: + """ + Get the state events for the current state of a room. + + Args: + 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 + """ + if not room_id: + raise ValueError(f"Expected a non-empty value for `room_id` but received {room_id!r}") + return self._get( + path_template("/_matrix/client/v3/rooms/{room_id}/state", room_id=room_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=StateListResponse, + ) + + +class AsyncStateResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncStateResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncStateResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncStateResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AsyncStateResourceWithStreamingResponse(self) + + async def retrieve( + self, + state_key: str, + *, + room_id: str, + event_type: str, + format: Literal["content", "event"] | 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> StateRetrieveResponse: + """Looks up the contents of a state event in a room. + + If the user is joined to the + room then the state is taken from the current state of the room. If the user has + left the room then the state is taken from the state of the room when they left. + + Args: + format: The format to use for the returned data. `content` (the default) will return + only the content of the state event. `event` will return the entire event in the + usual format suitable for clients, including fields like event ID, sender and + timestamp. + + 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 + """ + if not room_id: + raise ValueError(f"Expected a non-empty value for `room_id` but received {room_id!r}") + if not event_type: + raise ValueError(f"Expected a non-empty value for `event_type` but received {event_type!r}") + if not state_key: + raise ValueError(f"Expected a non-empty value for `state_key` but received {state_key!r}") + return await self._get( + path_template( + "/_matrix/client/v3/rooms/{room_id}/state/{event_type}/{state_key}", + room_id=room_id, + event_type=event_type, + state_key=state_key, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform({"format": format}, state_retrieve_params.StateRetrieveParams), + ), + cast_to=StateRetrieveResponse, + ) + + async def list( + self, + room_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> StateListResponse: + """ + Get the state events for the current state of a room. + + Args: + 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 + """ + if not room_id: + raise ValueError(f"Expected a non-empty value for `room_id` but received {room_id!r}") + return await self._get( + path_template("/_matrix/client/v3/rooms/{room_id}/state", room_id=room_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=StateListResponse, + ) + + +class StateResourceWithRawResponse: + def __init__(self, state: StateResource) -> None: + self._state = state + + self.retrieve = to_raw_response_wrapper( + state.retrieve, + ) + self.list = to_raw_response_wrapper( + state.list, + ) + + +class AsyncStateResourceWithRawResponse: + def __init__(self, state: AsyncStateResource) -> None: + self._state = state + + self.retrieve = async_to_raw_response_wrapper( + state.retrieve, + ) + self.list = async_to_raw_response_wrapper( + state.list, + ) + + +class StateResourceWithStreamingResponse: + def __init__(self, state: StateResource) -> None: + self._state = state + + self.retrieve = to_streamed_response_wrapper( + state.retrieve, + ) + self.list = to_streamed_response_wrapper( + state.list, + ) + + +class AsyncStateResourceWithStreamingResponse: + def __init__(self, state: AsyncStateResource) -> None: + self._state = state + + self.retrieve = async_to_streamed_response_wrapper( + state.retrieve, + ) + self.list = async_to_streamed_response_wrapper( + state.list, + ) diff --git a/src/beeper_desktop_api/resources/matrix/users/__init__.py b/src/beeper_desktop_api/resources/matrix/users/__init__.py new file mode 100644 index 0000000..84ad0d9 --- /dev/null +++ b/src/beeper_desktop_api/resources/matrix/users/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .users import ( + UsersResource, + AsyncUsersResource, + UsersResourceWithRawResponse, + AsyncUsersResourceWithRawResponse, + UsersResourceWithStreamingResponse, + AsyncUsersResourceWithStreamingResponse, +) +from .account_data import ( + AccountDataResource, + AsyncAccountDataResource, + AccountDataResourceWithRawResponse, + AsyncAccountDataResourceWithRawResponse, + AccountDataResourceWithStreamingResponse, + AsyncAccountDataResourceWithStreamingResponse, +) + +__all__ = [ + "AccountDataResource", + "AsyncAccountDataResource", + "AccountDataResourceWithRawResponse", + "AsyncAccountDataResourceWithRawResponse", + "AccountDataResourceWithStreamingResponse", + "AsyncAccountDataResourceWithStreamingResponse", + "UsersResource", + "AsyncUsersResource", + "UsersResourceWithRawResponse", + "AsyncUsersResourceWithRawResponse", + "UsersResourceWithStreamingResponse", + "AsyncUsersResourceWithStreamingResponse", +] diff --git a/src/beeper_desktop_api/resources/matrix/users/account_data.py b/src/beeper_desktop_api/resources/matrix/users/account_data.py new file mode 100644 index 0000000..2c8a316 --- /dev/null +++ b/src/beeper_desktop_api/resources/matrix/users/account_data.py @@ -0,0 +1,270 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ...._types import Body, Query, Headers, NotGiven, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +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 +from ....types.matrix.users import account_data_update_params + +__all__ = ["AccountDataResource", "AsyncAccountDataResource"] + + +class AccountDataResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> AccountDataResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AccountDataResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AccountDataResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AccountDataResourceWithStreamingResponse(self) + + def retrieve( + self, + type: str, + *, + user_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """Get some account data for the client. + + This config is only visible to the user + that set the account data. + + Args: + 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 + """ + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + if not type: + raise ValueError(f"Expected a non-empty value for `type` but received {type!r}") + return self._get( + path_template("/_matrix/client/v3/user/{user_id}/account_data/{type}", user_id=user_id, type=type), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=object, + ) + + def update( + self, + type: str, + *, + user_id: str, + body: object, + # 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: + """Set some account data for the client. + + This config is only visible to the user + that set the account data. The config will be available to clients through the + top-level `account_data` field in the homeserver response to + [/sync](https://spec.matrix.org/v1.18/client-server-api/#get_matrixclientv3sync). + + Args: + 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 + """ + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + if not type: + raise ValueError(f"Expected a non-empty value for `type` but received {type!r}") + return self._put( + path_template("/_matrix/client/v3/user/{user_id}/account_data/{type}", user_id=user_id, type=type), + body=maybe_transform(body, account_data_update_params.AccountDataUpdateParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=object, + ) + + +class AsyncAccountDataResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncAccountDataResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncAccountDataResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncAccountDataResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AsyncAccountDataResourceWithStreamingResponse(self) + + async def retrieve( + self, + type: str, + *, + user_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """Get some account data for the client. + + This config is only visible to the user + that set the account data. + + Args: + 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 + """ + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + if not type: + raise ValueError(f"Expected a non-empty value for `type` but received {type!r}") + return await self._get( + path_template("/_matrix/client/v3/user/{user_id}/account_data/{type}", user_id=user_id, type=type), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=object, + ) + + async def update( + self, + type: str, + *, + user_id: str, + body: object, + # 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: + """Set some account data for the client. + + This config is only visible to the user + that set the account data. The config will be available to clients through the + top-level `account_data` field in the homeserver response to + [/sync](https://spec.matrix.org/v1.18/client-server-api/#get_matrixclientv3sync). + + Args: + 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 + """ + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + if not type: + raise ValueError(f"Expected a non-empty value for `type` but received {type!r}") + return await self._put( + path_template("/_matrix/client/v3/user/{user_id}/account_data/{type}", user_id=user_id, type=type), + body=await async_maybe_transform(body, account_data_update_params.AccountDataUpdateParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=object, + ) + + +class AccountDataResourceWithRawResponse: + def __init__(self, account_data: AccountDataResource) -> None: + self._account_data = account_data + + self.retrieve = to_raw_response_wrapper( + account_data.retrieve, + ) + self.update = to_raw_response_wrapper( + account_data.update, + ) + + +class AsyncAccountDataResourceWithRawResponse: + def __init__(self, account_data: AsyncAccountDataResource) -> None: + self._account_data = account_data + + self.retrieve = async_to_raw_response_wrapper( + account_data.retrieve, + ) + self.update = async_to_raw_response_wrapper( + account_data.update, + ) + + +class AccountDataResourceWithStreamingResponse: + def __init__(self, account_data: AccountDataResource) -> None: + self._account_data = account_data + + self.retrieve = to_streamed_response_wrapper( + account_data.retrieve, + ) + self.update = to_streamed_response_wrapper( + account_data.update, + ) + + +class AsyncAccountDataResourceWithStreamingResponse: + def __init__(self, account_data: AsyncAccountDataResource) -> None: + self._account_data = account_data + + self.retrieve = async_to_streamed_response_wrapper( + account_data.retrieve, + ) + self.update = async_to_streamed_response_wrapper( + account_data.update, + ) diff --git a/src/beeper_desktop_api/resources/matrix/users/users.py b/src/beeper_desktop_api/resources/matrix/users/users.py new file mode 100644 index 0000000..f7bdfb6 --- /dev/null +++ b/src/beeper_desktop_api/resources/matrix/users/users.py @@ -0,0 +1,196 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ...._types import Body, Query, Headers, NotGiven, not_given +from ...._utils import path_template +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 .account_data import ( + AccountDataResource, + AsyncAccountDataResource, + AccountDataResourceWithRawResponse, + AsyncAccountDataResourceWithRawResponse, + AccountDataResourceWithStreamingResponse, + AsyncAccountDataResourceWithStreamingResponse, +) +from ...._base_client import make_request_options +from ....types.matrix.user_retrieve_profile_response import UserRetrieveProfileResponse + +__all__ = ["UsersResource", "AsyncUsersResource"] + + +class UsersResource(SyncAPIResource): + @cached_property + def account_data(self) -> AccountDataResource: + return AccountDataResource(self._client) + + @cached_property + def with_raw_response(self) -> UsersResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return UsersResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> UsersResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return UsersResourceWithStreamingResponse(self) + + def retrieve_profile( + self, + user_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> UserRetrieveProfileResponse: + """ + Get the complete profile for a user. + + Args: + 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 + """ + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + return self._get( + path_template("/_matrix/client/v3/profile/{user_id}", user_id=user_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=UserRetrieveProfileResponse, + ) + + +class AsyncUsersResource(AsyncAPIResource): + @cached_property + def account_data(self) -> AsyncAccountDataResource: + return AsyncAccountDataResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncUsersResourceWithRawResponse: + """ + 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/beeper/desktop-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncUsersResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncUsersResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/beeper/desktop-api-python#with_streaming_response + """ + return AsyncUsersResourceWithStreamingResponse(self) + + async def retrieve_profile( + self, + user_id: 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> UserRetrieveProfileResponse: + """ + Get the complete profile for a user. + + Args: + 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 + """ + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + return await self._get( + path_template("/_matrix/client/v3/profile/{user_id}", user_id=user_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=UserRetrieveProfileResponse, + ) + + +class UsersResourceWithRawResponse: + def __init__(self, users: UsersResource) -> None: + self._users = users + + self.retrieve_profile = to_raw_response_wrapper( + users.retrieve_profile, + ) + + @cached_property + def account_data(self) -> AccountDataResourceWithRawResponse: + return AccountDataResourceWithRawResponse(self._users.account_data) + + +class AsyncUsersResourceWithRawResponse: + def __init__(self, users: AsyncUsersResource) -> None: + self._users = users + + self.retrieve_profile = async_to_raw_response_wrapper( + users.retrieve_profile, + ) + + @cached_property + def account_data(self) -> AsyncAccountDataResourceWithRawResponse: + return AsyncAccountDataResourceWithRawResponse(self._users.account_data) + + +class UsersResourceWithStreamingResponse: + def __init__(self, users: UsersResource) -> None: + self._users = users + + self.retrieve_profile = to_streamed_response_wrapper( + users.retrieve_profile, + ) + + @cached_property + def account_data(self) -> AccountDataResourceWithStreamingResponse: + return AccountDataResourceWithStreamingResponse(self._users.account_data) + + +class AsyncUsersResourceWithStreamingResponse: + def __init__(self, users: AsyncUsersResource) -> None: + self._users = users + + self.retrieve_profile = async_to_streamed_response_wrapper( + users.retrieve_profile, + ) + + @cached_property + def account_data(self) -> AsyncAccountDataResourceWithStreamingResponse: + return AsyncAccountDataResourceWithStreamingResponse(self._users.account_data) diff --git a/src/beeper_desktop_api/types/__init__.py b/src/beeper_desktop_api/types/__init__.py index 78ec780..fdfcad3 100644 --- a/src/beeper_desktop_api/types/__init__.py +++ b/src/beeper_desktop_api/types/__init__.py @@ -3,7 +3,14 @@ from __future__ import annotations from .chat import Chat as Chat -from .shared import User as User, Error as Error, Message as Message, Reaction as Reaction, Attachment as Attachment +from .shared import ( + User as User, + Error as Error, + Message as Message, + Reaction as Reaction, + Attachment as Attachment, + AppStateSnapshot as AppStateSnapshot, +) from .account import Account as Account from .focus_response import FocusResponse as FocusResponse from .search_response import SearchResponse as SearchResponse @@ -14,12 +21,15 @@ from .chat_list_response import ChatListResponse as ChatListResponse from .chat_search_params import ChatSearchParams as ChatSearchParams from .chat_update_params import ChatUpdateParams as ChatUpdateParams +from .app_status_response import AppStatusResponse as AppStatusResponse from .asset_upload_params import AssetUploadParams as AssetUploadParams +from .bridge_availability import BridgeAvailability as BridgeAvailability from .chat_archive_params import ChatArchiveParams as ChatArchiveParams from .chat_start_response import ChatStartResponse as ChatStartResponse from .client_focus_params import ClientFocusParams as ClientFocusParams from .message_list_params import MessageListParams as MessageListParams from .message_send_params import MessageSendParams as MessageSendParams +from .bridge_list_response import BridgeListResponse as BridgeListResponse from .chat_create_response import ChatCreateResponse as ChatCreateResponse from .chat_retrieve_params import ChatRetrieveParams as ChatRetrieveParams from .client_search_params import ClientSearchParams as ClientSearchParams diff --git a/src/beeper_desktop_api/types/app/__init__.py b/src/beeper_desktop_api/types/app/__init__.py new file mode 100644 index 0000000..bf025a8 --- /dev/null +++ b/src/beeper_desktop_api/types/app/__init__.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .login_email_params import LoginEmailParams as LoginEmailParams +from .login_start_response import LoginStartResponse as LoginStartResponse +from .login_register_params import LoginRegisterParams as LoginRegisterParams +from .login_response_params import LoginResponseParams as LoginResponseParams +from .login_register_response import LoginRegisterResponse as LoginRegisterResponse +from .login_response_response import LoginResponseResponse as LoginResponseResponse diff --git a/src/beeper_desktop_api/types/app/e2ee/__init__.py b/src/beeper_desktop_api/types/app/e2ee/__init__.py new file mode 100644 index 0000000..2cd79cf --- /dev/null +++ b/src/beeper_desktop_api/types/app/e2ee/__init__.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .verification_cancel_params import VerificationCancelParams as VerificationCancelParams +from .verification_create_params import VerificationCreateParams as VerificationCreateParams +from .recovery_code_verify_params import RecoveryCodeVerifyParams as RecoveryCodeVerifyParams +from .verification_accept_response import VerificationAcceptResponse as VerificationAcceptResponse +from .verification_cancel_response import VerificationCancelResponse as VerificationCancelResponse +from .verification_create_response import VerificationCreateResponse as VerificationCreateResponse +from .recovery_code_verify_response import RecoveryCodeVerifyResponse as RecoveryCodeVerifyResponse +from .recovery_code_mark_backed_up_response import RecoveryCodeMarkBackedUpResponse as RecoveryCodeMarkBackedUpResponse diff --git a/src/beeper_desktop_api/types/app/e2ee/recovery_code/__init__.py b/src/beeper_desktop_api/types/app/e2ee/recovery_code/__init__.py new file mode 100644 index 0000000..0299c46 --- /dev/null +++ b/src/beeper_desktop_api/types/app/e2ee/recovery_code/__init__.py @@ -0,0 +1,8 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .reset_create_params import ResetCreateParams as ResetCreateParams +from .reset_confirm_params import ResetConfirmParams as ResetConfirmParams +from .reset_create_response import ResetCreateResponse as ResetCreateResponse +from .reset_confirm_response import ResetConfirmResponse as ResetConfirmResponse diff --git a/src/beeper_desktop_api/types/app/e2ee/recovery_code/reset_confirm_params.py b/src/beeper_desktop_api/types/app/e2ee/recovery_code/reset_confirm_params.py new file mode 100644 index 0000000..745927e --- /dev/null +++ b/src/beeper_desktop_api/types/app/e2ee/recovery_code/reset_confirm_params.py @@ -0,0 +1,14 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from ....._utils import PropertyInfo + +__all__ = ["ResetConfirmParams"] + + +class ResetConfirmParams(TypedDict, total=False): + recovery_code: Required[Annotated[str, PropertyInfo(alias="recoveryCode")]] + """New recovery key returned by the reset step.""" diff --git a/src/beeper_desktop_api/types/app/e2ee/recovery_code/reset_confirm_response.py b/src/beeper_desktop_api/types/app/e2ee/recovery_code/reset_confirm_response.py new file mode 100644 index 0000000..9ba8280 --- /dev/null +++ b/src/beeper_desktop_api/types/app/e2ee/recovery_code/reset_confirm_response.py @@ -0,0 +1,170 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ....._models import BaseModel + +__all__ = [ + "ResetConfirmResponse", + "AppState", + "AppStateE2ee", + "AppStateE2eeSecrets", + "AppStateMatrix", + "AppStateVerification", + "AppStateVerificationError", + "AppStateVerificationSas", +] + + +class AppStateE2eeSecrets(BaseModel): + """Encrypted messaging keys available on this device.""" + + master_key: bool = FieldInfo(alias="masterKey") + """Whether the account identity key is available.""" + + megolm_backup_key: bool = FieldInfo(alias="megolmBackupKey") + """Whether the encrypted message backup key is available.""" + + recovery_code: bool = FieldInfo(alias="recoveryCode") + """Whether a recovery key is available.""" + + self_signing_key: bool = FieldInfo(alias="selfSigningKey") + """Whether the device trust key is available.""" + + user_signing_key: bool = FieldInfo(alias="userSigningKey") + """Whether the user trust key is available.""" + + +class AppStateE2ee(BaseModel): + """Encrypted messaging setup status.""" + + cross_signing: bool = FieldInfo(alias="crossSigning") + """Whether this account can verify trusted devices.""" + + first_sync_done: bool = FieldInfo(alias="firstSyncDone") + """Whether the first encrypted message sync is complete.""" + + has_backed_up_code: bool = FieldInfo(alias="hasBackedUpCode") + """Whether the user confirmed that they saved their recovery key.""" + + initialized: bool + """Whether encrypted messaging setup has started.""" + + key_backup: bool = FieldInfo(alias="keyBackup") + """Whether encrypted message backup is available.""" + + secrets: AppStateE2eeSecrets + """Encrypted messaging keys available on this device.""" + + secret_storage: bool = FieldInfo(alias="secretStorage") + """Whether secure key storage is available.""" + + verified: bool + """Whether this device is trusted for encrypted messages.""" + + recovery_code_generated_at: Optional[float] = FieldInfo(alias="recoveryCodeGeneratedAt", default=None) + """Unix timestamp for when the recovery key was created.""" + + +class AppStateMatrix(BaseModel): + """Signed-in account details. Omitted until sign-in is complete.""" + + device_id: str = FieldInfo(alias="deviceID") + """Current device ID.""" + + homeserver: str + """Beeper server URL for this account.""" + + user_id: str = FieldInfo(alias="userID") + """Signed-in Beeper user ID.""" + + +class AppStateVerificationError(BaseModel): + """Verification error details, if verification stopped.""" + + code: str + """Verification error code.""" + + reason: str + """User-facing verification error message.""" + + +class AppStateVerificationSas(BaseModel): + """Emoji or number comparison data for verification.""" + + decimals: str + """Number sequence to compare on both devices.""" + + emojis: str + """Emoji sequence to compare on both devices.""" + + +class AppStateVerification(BaseModel): + """Trusted-device verification progress.""" + + available_actions: List[ + Literal["create", "qr.scan", "accept", "cancel", "qr.confirmScanned", "sas.start", "sas.confirm"] + ] = FieldInfo(alias="availableActions") + """Verification actions that are valid for the current state.""" + + state: Literal["idle", "requested", "ready", "sas_ready", "qr_scanned", "done", "cancelled", "error"] + """Current trusted-device verification state.""" + + error: Optional[AppStateVerificationError] = None + """Verification error details, if verification stopped.""" + + from_: Optional[str] = FieldInfo(alias="from", default=None) + """User ID that started verification.""" + + from_device: Optional[str] = FieldInfo(alias="fromDevice", default=None) + """Device that started verification.""" + + other_device: Optional[str] = FieldInfo(alias="otherDevice", default=None) + """Other device participating in verification.""" + + qr_data: Optional[str] = FieldInfo(alias="qrData", default=None) + """QR code payload to display for verification.""" + + sas: Optional[AppStateVerificationSas] = None + """Emoji or number comparison data for verification.""" + + supports_sas: Optional[bool] = FieldInfo(alias="supportsSAS", default=None) + """Whether emoji comparison is available.""" + + supports_scan_qr_code: Optional[bool] = FieldInfo(alias="supportsScanQRCode", default=None) + """Whether QR code verification is available.""" + + verification_id: Optional[str] = FieldInfo(alias="verificationID", default=None) + """Verification ID to pass in verification action paths.""" + + +class AppState(BaseModel): + """Current onboarding state after the requested step.""" + + e2ee: AppStateE2ee + """Encrypted messaging setup status.""" + + state: Literal[ + "needs-login", + "initializing", + "needs-cross-signing-setup", + "needs-verification", + "needs-secrets", + "needs-first-sync", + "ready", + ] + """Current onboarding state for Beeper Desktop.""" + + matrix: Optional[AppStateMatrix] = None + """Signed-in account details. Omitted until sign-in is complete.""" + + verification: Optional[AppStateVerification] = None + """Trusted-device verification progress.""" + + +class ResetConfirmResponse(BaseModel): + app_state: AppState = FieldInfo(alias="appState") + """Current onboarding state after the requested step.""" diff --git a/src/beeper_desktop_api/types/app/e2ee/recovery_code/reset_create_params.py b/src/beeper_desktop_api/types/app/e2ee/recovery_code/reset_create_params.py new file mode 100644 index 0000000..05928a2 --- /dev/null +++ b/src/beeper_desktop_api/types/app/e2ee/recovery_code/reset_create_params.py @@ -0,0 +1,14 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Annotated, TypedDict + +from ....._utils import PropertyInfo + +__all__ = ["ResetCreateParams"] + + +class ResetCreateParams(TypedDict, total=False): + recovery_code: Annotated[str, PropertyInfo(alias="recoveryCode")] + """Existing recovery key, if the user has it.""" diff --git a/src/beeper_desktop_api/types/app/e2ee/recovery_code/reset_create_response.py b/src/beeper_desktop_api/types/app/e2ee/recovery_code/reset_create_response.py new file mode 100644 index 0000000..8efd2b0 --- /dev/null +++ b/src/beeper_desktop_api/types/app/e2ee/recovery_code/reset_create_response.py @@ -0,0 +1,173 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ....._models import BaseModel + +__all__ = [ + "ResetCreateResponse", + "AppState", + "AppStateE2ee", + "AppStateE2eeSecrets", + "AppStateMatrix", + "AppStateVerification", + "AppStateVerificationError", + "AppStateVerificationSas", +] + + +class AppStateE2eeSecrets(BaseModel): + """Encrypted messaging keys available on this device.""" + + master_key: bool = FieldInfo(alias="masterKey") + """Whether the account identity key is available.""" + + megolm_backup_key: bool = FieldInfo(alias="megolmBackupKey") + """Whether the encrypted message backup key is available.""" + + recovery_code: bool = FieldInfo(alias="recoveryCode") + """Whether a recovery key is available.""" + + self_signing_key: bool = FieldInfo(alias="selfSigningKey") + """Whether the device trust key is available.""" + + user_signing_key: bool = FieldInfo(alias="userSigningKey") + """Whether the user trust key is available.""" + + +class AppStateE2ee(BaseModel): + """Encrypted messaging setup status.""" + + cross_signing: bool = FieldInfo(alias="crossSigning") + """Whether this account can verify trusted devices.""" + + first_sync_done: bool = FieldInfo(alias="firstSyncDone") + """Whether the first encrypted message sync is complete.""" + + has_backed_up_code: bool = FieldInfo(alias="hasBackedUpCode") + """Whether the user confirmed that they saved their recovery key.""" + + initialized: bool + """Whether encrypted messaging setup has started.""" + + key_backup: bool = FieldInfo(alias="keyBackup") + """Whether encrypted message backup is available.""" + + secrets: AppStateE2eeSecrets + """Encrypted messaging keys available on this device.""" + + secret_storage: bool = FieldInfo(alias="secretStorage") + """Whether secure key storage is available.""" + + verified: bool + """Whether this device is trusted for encrypted messages.""" + + recovery_code_generated_at: Optional[float] = FieldInfo(alias="recoveryCodeGeneratedAt", default=None) + """Unix timestamp for when the recovery key was created.""" + + +class AppStateMatrix(BaseModel): + """Signed-in account details. Omitted until sign-in is complete.""" + + device_id: str = FieldInfo(alias="deviceID") + """Current device ID.""" + + homeserver: str + """Beeper server URL for this account.""" + + user_id: str = FieldInfo(alias="userID") + """Signed-in Beeper user ID.""" + + +class AppStateVerificationError(BaseModel): + """Verification error details, if verification stopped.""" + + code: str + """Verification error code.""" + + reason: str + """User-facing verification error message.""" + + +class AppStateVerificationSas(BaseModel): + """Emoji or number comparison data for verification.""" + + decimals: str + """Number sequence to compare on both devices.""" + + emojis: str + """Emoji sequence to compare on both devices.""" + + +class AppStateVerification(BaseModel): + """Trusted-device verification progress.""" + + available_actions: List[ + Literal["create", "qr.scan", "accept", "cancel", "qr.confirmScanned", "sas.start", "sas.confirm"] + ] = FieldInfo(alias="availableActions") + """Verification actions that are valid for the current state.""" + + state: Literal["idle", "requested", "ready", "sas_ready", "qr_scanned", "done", "cancelled", "error"] + """Current trusted-device verification state.""" + + error: Optional[AppStateVerificationError] = None + """Verification error details, if verification stopped.""" + + from_: Optional[str] = FieldInfo(alias="from", default=None) + """User ID that started verification.""" + + from_device: Optional[str] = FieldInfo(alias="fromDevice", default=None) + """Device that started verification.""" + + other_device: Optional[str] = FieldInfo(alias="otherDevice", default=None) + """Other device participating in verification.""" + + qr_data: Optional[str] = FieldInfo(alias="qrData", default=None) + """QR code payload to display for verification.""" + + sas: Optional[AppStateVerificationSas] = None + """Emoji or number comparison data for verification.""" + + supports_sas: Optional[bool] = FieldInfo(alias="supportsSAS", default=None) + """Whether emoji comparison is available.""" + + supports_scan_qr_code: Optional[bool] = FieldInfo(alias="supportsScanQRCode", default=None) + """Whether QR code verification is available.""" + + verification_id: Optional[str] = FieldInfo(alias="verificationID", default=None) + """Verification ID to pass in verification action paths.""" + + +class AppState(BaseModel): + """Current onboarding state after creating the new recovery key.""" + + e2ee: AppStateE2ee + """Encrypted messaging setup status.""" + + state: Literal[ + "needs-login", + "initializing", + "needs-cross-signing-setup", + "needs-verification", + "needs-secrets", + "needs-first-sync", + "ready", + ] + """Current onboarding state for Beeper Desktop.""" + + matrix: Optional[AppStateMatrix] = None + """Signed-in account details. Omitted until sign-in is complete.""" + + verification: Optional[AppStateVerification] = None + """Trusted-device verification progress.""" + + +class ResetCreateResponse(BaseModel): + app_state: AppState = FieldInfo(alias="appState") + """Current onboarding state after creating the new recovery key.""" + + recovery_code: str = FieldInfo(alias="recoveryCode") + """New recovery key. Show it once and ask the user to save it.""" diff --git a/src/beeper_desktop_api/types/app/e2ee/recovery_code_mark_backed_up_response.py b/src/beeper_desktop_api/types/app/e2ee/recovery_code_mark_backed_up_response.py new file mode 100644 index 0000000..a9b8f1d --- /dev/null +++ b/src/beeper_desktop_api/types/app/e2ee/recovery_code_mark_backed_up_response.py @@ -0,0 +1,170 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ...._models import BaseModel + +__all__ = [ + "RecoveryCodeMarkBackedUpResponse", + "AppState", + "AppStateE2ee", + "AppStateE2eeSecrets", + "AppStateMatrix", + "AppStateVerification", + "AppStateVerificationError", + "AppStateVerificationSas", +] + + +class AppStateE2eeSecrets(BaseModel): + """Encrypted messaging keys available on this device.""" + + master_key: bool = FieldInfo(alias="masterKey") + """Whether the account identity key is available.""" + + megolm_backup_key: bool = FieldInfo(alias="megolmBackupKey") + """Whether the encrypted message backup key is available.""" + + recovery_code: bool = FieldInfo(alias="recoveryCode") + """Whether a recovery key is available.""" + + self_signing_key: bool = FieldInfo(alias="selfSigningKey") + """Whether the device trust key is available.""" + + user_signing_key: bool = FieldInfo(alias="userSigningKey") + """Whether the user trust key is available.""" + + +class AppStateE2ee(BaseModel): + """Encrypted messaging setup status.""" + + cross_signing: bool = FieldInfo(alias="crossSigning") + """Whether this account can verify trusted devices.""" + + first_sync_done: bool = FieldInfo(alias="firstSyncDone") + """Whether the first encrypted message sync is complete.""" + + has_backed_up_code: bool = FieldInfo(alias="hasBackedUpCode") + """Whether the user confirmed that they saved their recovery key.""" + + initialized: bool + """Whether encrypted messaging setup has started.""" + + key_backup: bool = FieldInfo(alias="keyBackup") + """Whether encrypted message backup is available.""" + + secrets: AppStateE2eeSecrets + """Encrypted messaging keys available on this device.""" + + secret_storage: bool = FieldInfo(alias="secretStorage") + """Whether secure key storage is available.""" + + verified: bool + """Whether this device is trusted for encrypted messages.""" + + recovery_code_generated_at: Optional[float] = FieldInfo(alias="recoveryCodeGeneratedAt", default=None) + """Unix timestamp for when the recovery key was created.""" + + +class AppStateMatrix(BaseModel): + """Signed-in account details. Omitted until sign-in is complete.""" + + device_id: str = FieldInfo(alias="deviceID") + """Current device ID.""" + + homeserver: str + """Beeper server URL for this account.""" + + user_id: str = FieldInfo(alias="userID") + """Signed-in Beeper user ID.""" + + +class AppStateVerificationError(BaseModel): + """Verification error details, if verification stopped.""" + + code: str + """Verification error code.""" + + reason: str + """User-facing verification error message.""" + + +class AppStateVerificationSas(BaseModel): + """Emoji or number comparison data for verification.""" + + decimals: str + """Number sequence to compare on both devices.""" + + emojis: str + """Emoji sequence to compare on both devices.""" + + +class AppStateVerification(BaseModel): + """Trusted-device verification progress.""" + + available_actions: List[ + Literal["create", "qr.scan", "accept", "cancel", "qr.confirmScanned", "sas.start", "sas.confirm"] + ] = FieldInfo(alias="availableActions") + """Verification actions that are valid for the current state.""" + + state: Literal["idle", "requested", "ready", "sas_ready", "qr_scanned", "done", "cancelled", "error"] + """Current trusted-device verification state.""" + + error: Optional[AppStateVerificationError] = None + """Verification error details, if verification stopped.""" + + from_: Optional[str] = FieldInfo(alias="from", default=None) + """User ID that started verification.""" + + from_device: Optional[str] = FieldInfo(alias="fromDevice", default=None) + """Device that started verification.""" + + other_device: Optional[str] = FieldInfo(alias="otherDevice", default=None) + """Other device participating in verification.""" + + qr_data: Optional[str] = FieldInfo(alias="qrData", default=None) + """QR code payload to display for verification.""" + + sas: Optional[AppStateVerificationSas] = None + """Emoji or number comparison data for verification.""" + + supports_sas: Optional[bool] = FieldInfo(alias="supportsSAS", default=None) + """Whether emoji comparison is available.""" + + supports_scan_qr_code: Optional[bool] = FieldInfo(alias="supportsScanQRCode", default=None) + """Whether QR code verification is available.""" + + verification_id: Optional[str] = FieldInfo(alias="verificationID", default=None) + """Verification ID to pass in verification action paths.""" + + +class AppState(BaseModel): + """Current onboarding state after the requested step.""" + + e2ee: AppStateE2ee + """Encrypted messaging setup status.""" + + state: Literal[ + "needs-login", + "initializing", + "needs-cross-signing-setup", + "needs-verification", + "needs-secrets", + "needs-first-sync", + "ready", + ] + """Current onboarding state for Beeper Desktop.""" + + matrix: Optional[AppStateMatrix] = None + """Signed-in account details. Omitted until sign-in is complete.""" + + verification: Optional[AppStateVerification] = None + """Trusted-device verification progress.""" + + +class RecoveryCodeMarkBackedUpResponse(BaseModel): + app_state: AppState = FieldInfo(alias="appState") + """Current onboarding state after the requested step.""" diff --git a/src/beeper_desktop_api/types/app/e2ee/recovery_code_verify_params.py b/src/beeper_desktop_api/types/app/e2ee/recovery_code_verify_params.py new file mode 100644 index 0000000..9869a2d --- /dev/null +++ b/src/beeper_desktop_api/types/app/e2ee/recovery_code_verify_params.py @@ -0,0 +1,14 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from ...._utils import PropertyInfo + +__all__ = ["RecoveryCodeVerifyParams"] + + +class RecoveryCodeVerifyParams(TypedDict, total=False): + recovery_code: Required[Annotated[str, PropertyInfo(alias="recoveryCode")]] + """Recovery key saved by the user.""" diff --git a/src/beeper_desktop_api/types/app/e2ee/recovery_code_verify_response.py b/src/beeper_desktop_api/types/app/e2ee/recovery_code_verify_response.py new file mode 100644 index 0000000..4af7794 --- /dev/null +++ b/src/beeper_desktop_api/types/app/e2ee/recovery_code_verify_response.py @@ -0,0 +1,170 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ...._models import BaseModel + +__all__ = [ + "RecoveryCodeVerifyResponse", + "AppState", + "AppStateE2ee", + "AppStateE2eeSecrets", + "AppStateMatrix", + "AppStateVerification", + "AppStateVerificationError", + "AppStateVerificationSas", +] + + +class AppStateE2eeSecrets(BaseModel): + """Encrypted messaging keys available on this device.""" + + master_key: bool = FieldInfo(alias="masterKey") + """Whether the account identity key is available.""" + + megolm_backup_key: bool = FieldInfo(alias="megolmBackupKey") + """Whether the encrypted message backup key is available.""" + + recovery_code: bool = FieldInfo(alias="recoveryCode") + """Whether a recovery key is available.""" + + self_signing_key: bool = FieldInfo(alias="selfSigningKey") + """Whether the device trust key is available.""" + + user_signing_key: bool = FieldInfo(alias="userSigningKey") + """Whether the user trust key is available.""" + + +class AppStateE2ee(BaseModel): + """Encrypted messaging setup status.""" + + cross_signing: bool = FieldInfo(alias="crossSigning") + """Whether this account can verify trusted devices.""" + + first_sync_done: bool = FieldInfo(alias="firstSyncDone") + """Whether the first encrypted message sync is complete.""" + + has_backed_up_code: bool = FieldInfo(alias="hasBackedUpCode") + """Whether the user confirmed that they saved their recovery key.""" + + initialized: bool + """Whether encrypted messaging setup has started.""" + + key_backup: bool = FieldInfo(alias="keyBackup") + """Whether encrypted message backup is available.""" + + secrets: AppStateE2eeSecrets + """Encrypted messaging keys available on this device.""" + + secret_storage: bool = FieldInfo(alias="secretStorage") + """Whether secure key storage is available.""" + + verified: bool + """Whether this device is trusted for encrypted messages.""" + + recovery_code_generated_at: Optional[float] = FieldInfo(alias="recoveryCodeGeneratedAt", default=None) + """Unix timestamp for when the recovery key was created.""" + + +class AppStateMatrix(BaseModel): + """Signed-in account details. Omitted until sign-in is complete.""" + + device_id: str = FieldInfo(alias="deviceID") + """Current device ID.""" + + homeserver: str + """Beeper server URL for this account.""" + + user_id: str = FieldInfo(alias="userID") + """Signed-in Beeper user ID.""" + + +class AppStateVerificationError(BaseModel): + """Verification error details, if verification stopped.""" + + code: str + """Verification error code.""" + + reason: str + """User-facing verification error message.""" + + +class AppStateVerificationSas(BaseModel): + """Emoji or number comparison data for verification.""" + + decimals: str + """Number sequence to compare on both devices.""" + + emojis: str + """Emoji sequence to compare on both devices.""" + + +class AppStateVerification(BaseModel): + """Trusted-device verification progress.""" + + available_actions: List[ + Literal["create", "qr.scan", "accept", "cancel", "qr.confirmScanned", "sas.start", "sas.confirm"] + ] = FieldInfo(alias="availableActions") + """Verification actions that are valid for the current state.""" + + state: Literal["idle", "requested", "ready", "sas_ready", "qr_scanned", "done", "cancelled", "error"] + """Current trusted-device verification state.""" + + error: Optional[AppStateVerificationError] = None + """Verification error details, if verification stopped.""" + + from_: Optional[str] = FieldInfo(alias="from", default=None) + """User ID that started verification.""" + + from_device: Optional[str] = FieldInfo(alias="fromDevice", default=None) + """Device that started verification.""" + + other_device: Optional[str] = FieldInfo(alias="otherDevice", default=None) + """Other device participating in verification.""" + + qr_data: Optional[str] = FieldInfo(alias="qrData", default=None) + """QR code payload to display for verification.""" + + sas: Optional[AppStateVerificationSas] = None + """Emoji or number comparison data for verification.""" + + supports_sas: Optional[bool] = FieldInfo(alias="supportsSAS", default=None) + """Whether emoji comparison is available.""" + + supports_scan_qr_code: Optional[bool] = FieldInfo(alias="supportsScanQRCode", default=None) + """Whether QR code verification is available.""" + + verification_id: Optional[str] = FieldInfo(alias="verificationID", default=None) + """Verification ID to pass in verification action paths.""" + + +class AppState(BaseModel): + """Current onboarding state after the requested step.""" + + e2ee: AppStateE2ee + """Encrypted messaging setup status.""" + + state: Literal[ + "needs-login", + "initializing", + "needs-cross-signing-setup", + "needs-verification", + "needs-secrets", + "needs-first-sync", + "ready", + ] + """Current onboarding state for Beeper Desktop.""" + + matrix: Optional[AppStateMatrix] = None + """Signed-in account details. Omitted until sign-in is complete.""" + + verification: Optional[AppStateVerification] = None + """Trusted-device verification progress.""" + + +class RecoveryCodeVerifyResponse(BaseModel): + app_state: AppState = FieldInfo(alias="appState") + """Current onboarding state after the requested step.""" diff --git a/src/beeper_desktop_api/types/app/e2ee/verification/__init__.py b/src/beeper_desktop_api/types/app/e2ee/verification/__init__.py new file mode 100644 index 0000000..d0eff7c --- /dev/null +++ b/src/beeper_desktop_api/types/app/e2ee/verification/__init__.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .qr_scan_params import QrScanParams as QrScanParams +from .qr_scan_response import QrScanResponse as QrScanResponse +from .sa_start_response import SaStartResponse as SaStartResponse +from .sa_confirm_response import SaConfirmResponse as SaConfirmResponse +from .qr_confirm_scanned_response import QrConfirmScannedResponse as QrConfirmScannedResponse diff --git a/src/beeper_desktop_api/types/app/e2ee/verification/qr_confirm_scanned_response.py b/src/beeper_desktop_api/types/app/e2ee/verification/qr_confirm_scanned_response.py new file mode 100644 index 0000000..a2032d8 --- /dev/null +++ b/src/beeper_desktop_api/types/app/e2ee/verification/qr_confirm_scanned_response.py @@ -0,0 +1,170 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ....._models import BaseModel + +__all__ = [ + "QrConfirmScannedResponse", + "AppState", + "AppStateE2ee", + "AppStateE2eeSecrets", + "AppStateMatrix", + "AppStateVerification", + "AppStateVerificationError", + "AppStateVerificationSas", +] + + +class AppStateE2eeSecrets(BaseModel): + """Encrypted messaging keys available on this device.""" + + master_key: bool = FieldInfo(alias="masterKey") + """Whether the account identity key is available.""" + + megolm_backup_key: bool = FieldInfo(alias="megolmBackupKey") + """Whether the encrypted message backup key is available.""" + + recovery_code: bool = FieldInfo(alias="recoveryCode") + """Whether a recovery key is available.""" + + self_signing_key: bool = FieldInfo(alias="selfSigningKey") + """Whether the device trust key is available.""" + + user_signing_key: bool = FieldInfo(alias="userSigningKey") + """Whether the user trust key is available.""" + + +class AppStateE2ee(BaseModel): + """Encrypted messaging setup status.""" + + cross_signing: bool = FieldInfo(alias="crossSigning") + """Whether this account can verify trusted devices.""" + + first_sync_done: bool = FieldInfo(alias="firstSyncDone") + """Whether the first encrypted message sync is complete.""" + + has_backed_up_code: bool = FieldInfo(alias="hasBackedUpCode") + """Whether the user confirmed that they saved their recovery key.""" + + initialized: bool + """Whether encrypted messaging setup has started.""" + + key_backup: bool = FieldInfo(alias="keyBackup") + """Whether encrypted message backup is available.""" + + secrets: AppStateE2eeSecrets + """Encrypted messaging keys available on this device.""" + + secret_storage: bool = FieldInfo(alias="secretStorage") + """Whether secure key storage is available.""" + + verified: bool + """Whether this device is trusted for encrypted messages.""" + + recovery_code_generated_at: Optional[float] = FieldInfo(alias="recoveryCodeGeneratedAt", default=None) + """Unix timestamp for when the recovery key was created.""" + + +class AppStateMatrix(BaseModel): + """Signed-in account details. Omitted until sign-in is complete.""" + + device_id: str = FieldInfo(alias="deviceID") + """Current device ID.""" + + homeserver: str + """Beeper server URL for this account.""" + + user_id: str = FieldInfo(alias="userID") + """Signed-in Beeper user ID.""" + + +class AppStateVerificationError(BaseModel): + """Verification error details, if verification stopped.""" + + code: str + """Verification error code.""" + + reason: str + """User-facing verification error message.""" + + +class AppStateVerificationSas(BaseModel): + """Emoji or number comparison data for verification.""" + + decimals: str + """Number sequence to compare on both devices.""" + + emojis: str + """Emoji sequence to compare on both devices.""" + + +class AppStateVerification(BaseModel): + """Trusted-device verification progress.""" + + available_actions: List[ + Literal["create", "qr.scan", "accept", "cancel", "qr.confirmScanned", "sas.start", "sas.confirm"] + ] = FieldInfo(alias="availableActions") + """Verification actions that are valid for the current state.""" + + state: Literal["idle", "requested", "ready", "sas_ready", "qr_scanned", "done", "cancelled", "error"] + """Current trusted-device verification state.""" + + error: Optional[AppStateVerificationError] = None + """Verification error details, if verification stopped.""" + + from_: Optional[str] = FieldInfo(alias="from", default=None) + """User ID that started verification.""" + + from_device: Optional[str] = FieldInfo(alias="fromDevice", default=None) + """Device that started verification.""" + + other_device: Optional[str] = FieldInfo(alias="otherDevice", default=None) + """Other device participating in verification.""" + + qr_data: Optional[str] = FieldInfo(alias="qrData", default=None) + """QR code payload to display for verification.""" + + sas: Optional[AppStateVerificationSas] = None + """Emoji or number comparison data for verification.""" + + supports_sas: Optional[bool] = FieldInfo(alias="supportsSAS", default=None) + """Whether emoji comparison is available.""" + + supports_scan_qr_code: Optional[bool] = FieldInfo(alias="supportsScanQRCode", default=None) + """Whether QR code verification is available.""" + + verification_id: Optional[str] = FieldInfo(alias="verificationID", default=None) + """Verification ID to pass in verification action paths.""" + + +class AppState(BaseModel): + """Current onboarding state after the requested step.""" + + e2ee: AppStateE2ee + """Encrypted messaging setup status.""" + + state: Literal[ + "needs-login", + "initializing", + "needs-cross-signing-setup", + "needs-verification", + "needs-secrets", + "needs-first-sync", + "ready", + ] + """Current onboarding state for Beeper Desktop.""" + + matrix: Optional[AppStateMatrix] = None + """Signed-in account details. Omitted until sign-in is complete.""" + + verification: Optional[AppStateVerification] = None + """Trusted-device verification progress.""" + + +class QrConfirmScannedResponse(BaseModel): + app_state: AppState = FieldInfo(alias="appState") + """Current onboarding state after the requested step.""" diff --git a/src/beeper_desktop_api/types/app/e2ee/verification/qr_scan_params.py b/src/beeper_desktop_api/types/app/e2ee/verification/qr_scan_params.py new file mode 100644 index 0000000..a16f78e --- /dev/null +++ b/src/beeper_desktop_api/types/app/e2ee/verification/qr_scan_params.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["QrScanParams"] + + +class QrScanParams(TypedDict, total=False): + data: Required[str] + """QR code payload scanned from the other device.""" diff --git a/src/beeper_desktop_api/types/app/e2ee/verification/qr_scan_response.py b/src/beeper_desktop_api/types/app/e2ee/verification/qr_scan_response.py new file mode 100644 index 0000000..ef7014b --- /dev/null +++ b/src/beeper_desktop_api/types/app/e2ee/verification/qr_scan_response.py @@ -0,0 +1,170 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ....._models import BaseModel + +__all__ = [ + "QrScanResponse", + "AppState", + "AppStateE2ee", + "AppStateE2eeSecrets", + "AppStateMatrix", + "AppStateVerification", + "AppStateVerificationError", + "AppStateVerificationSas", +] + + +class AppStateE2eeSecrets(BaseModel): + """Encrypted messaging keys available on this device.""" + + master_key: bool = FieldInfo(alias="masterKey") + """Whether the account identity key is available.""" + + megolm_backup_key: bool = FieldInfo(alias="megolmBackupKey") + """Whether the encrypted message backup key is available.""" + + recovery_code: bool = FieldInfo(alias="recoveryCode") + """Whether a recovery key is available.""" + + self_signing_key: bool = FieldInfo(alias="selfSigningKey") + """Whether the device trust key is available.""" + + user_signing_key: bool = FieldInfo(alias="userSigningKey") + """Whether the user trust key is available.""" + + +class AppStateE2ee(BaseModel): + """Encrypted messaging setup status.""" + + cross_signing: bool = FieldInfo(alias="crossSigning") + """Whether this account can verify trusted devices.""" + + first_sync_done: bool = FieldInfo(alias="firstSyncDone") + """Whether the first encrypted message sync is complete.""" + + has_backed_up_code: bool = FieldInfo(alias="hasBackedUpCode") + """Whether the user confirmed that they saved their recovery key.""" + + initialized: bool + """Whether encrypted messaging setup has started.""" + + key_backup: bool = FieldInfo(alias="keyBackup") + """Whether encrypted message backup is available.""" + + secrets: AppStateE2eeSecrets + """Encrypted messaging keys available on this device.""" + + secret_storage: bool = FieldInfo(alias="secretStorage") + """Whether secure key storage is available.""" + + verified: bool + """Whether this device is trusted for encrypted messages.""" + + recovery_code_generated_at: Optional[float] = FieldInfo(alias="recoveryCodeGeneratedAt", default=None) + """Unix timestamp for when the recovery key was created.""" + + +class AppStateMatrix(BaseModel): + """Signed-in account details. Omitted until sign-in is complete.""" + + device_id: str = FieldInfo(alias="deviceID") + """Current device ID.""" + + homeserver: str + """Beeper server URL for this account.""" + + user_id: str = FieldInfo(alias="userID") + """Signed-in Beeper user ID.""" + + +class AppStateVerificationError(BaseModel): + """Verification error details, if verification stopped.""" + + code: str + """Verification error code.""" + + reason: str + """User-facing verification error message.""" + + +class AppStateVerificationSas(BaseModel): + """Emoji or number comparison data for verification.""" + + decimals: str + """Number sequence to compare on both devices.""" + + emojis: str + """Emoji sequence to compare on both devices.""" + + +class AppStateVerification(BaseModel): + """Trusted-device verification progress.""" + + available_actions: List[ + Literal["create", "qr.scan", "accept", "cancel", "qr.confirmScanned", "sas.start", "sas.confirm"] + ] = FieldInfo(alias="availableActions") + """Verification actions that are valid for the current state.""" + + state: Literal["idle", "requested", "ready", "sas_ready", "qr_scanned", "done", "cancelled", "error"] + """Current trusted-device verification state.""" + + error: Optional[AppStateVerificationError] = None + """Verification error details, if verification stopped.""" + + from_: Optional[str] = FieldInfo(alias="from", default=None) + """User ID that started verification.""" + + from_device: Optional[str] = FieldInfo(alias="fromDevice", default=None) + """Device that started verification.""" + + other_device: Optional[str] = FieldInfo(alias="otherDevice", default=None) + """Other device participating in verification.""" + + qr_data: Optional[str] = FieldInfo(alias="qrData", default=None) + """QR code payload to display for verification.""" + + sas: Optional[AppStateVerificationSas] = None + """Emoji or number comparison data for verification.""" + + supports_sas: Optional[bool] = FieldInfo(alias="supportsSAS", default=None) + """Whether emoji comparison is available.""" + + supports_scan_qr_code: Optional[bool] = FieldInfo(alias="supportsScanQRCode", default=None) + """Whether QR code verification is available.""" + + verification_id: Optional[str] = FieldInfo(alias="verificationID", default=None) + """Verification ID to pass in verification action paths.""" + + +class AppState(BaseModel): + """Current onboarding state after the requested step.""" + + e2ee: AppStateE2ee + """Encrypted messaging setup status.""" + + state: Literal[ + "needs-login", + "initializing", + "needs-cross-signing-setup", + "needs-verification", + "needs-secrets", + "needs-first-sync", + "ready", + ] + """Current onboarding state for Beeper Desktop.""" + + matrix: Optional[AppStateMatrix] = None + """Signed-in account details. Omitted until sign-in is complete.""" + + verification: Optional[AppStateVerification] = None + """Trusted-device verification progress.""" + + +class QrScanResponse(BaseModel): + app_state: AppState = FieldInfo(alias="appState") + """Current onboarding state after the requested step.""" diff --git a/src/beeper_desktop_api/types/app/e2ee/verification/sa_confirm_response.py b/src/beeper_desktop_api/types/app/e2ee/verification/sa_confirm_response.py new file mode 100644 index 0000000..9f90136 --- /dev/null +++ b/src/beeper_desktop_api/types/app/e2ee/verification/sa_confirm_response.py @@ -0,0 +1,170 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ....._models import BaseModel + +__all__ = [ + "SaConfirmResponse", + "AppState", + "AppStateE2ee", + "AppStateE2eeSecrets", + "AppStateMatrix", + "AppStateVerification", + "AppStateVerificationError", + "AppStateVerificationSas", +] + + +class AppStateE2eeSecrets(BaseModel): + """Encrypted messaging keys available on this device.""" + + master_key: bool = FieldInfo(alias="masterKey") + """Whether the account identity key is available.""" + + megolm_backup_key: bool = FieldInfo(alias="megolmBackupKey") + """Whether the encrypted message backup key is available.""" + + recovery_code: bool = FieldInfo(alias="recoveryCode") + """Whether a recovery key is available.""" + + self_signing_key: bool = FieldInfo(alias="selfSigningKey") + """Whether the device trust key is available.""" + + user_signing_key: bool = FieldInfo(alias="userSigningKey") + """Whether the user trust key is available.""" + + +class AppStateE2ee(BaseModel): + """Encrypted messaging setup status.""" + + cross_signing: bool = FieldInfo(alias="crossSigning") + """Whether this account can verify trusted devices.""" + + first_sync_done: bool = FieldInfo(alias="firstSyncDone") + """Whether the first encrypted message sync is complete.""" + + has_backed_up_code: bool = FieldInfo(alias="hasBackedUpCode") + """Whether the user confirmed that they saved their recovery key.""" + + initialized: bool + """Whether encrypted messaging setup has started.""" + + key_backup: bool = FieldInfo(alias="keyBackup") + """Whether encrypted message backup is available.""" + + secrets: AppStateE2eeSecrets + """Encrypted messaging keys available on this device.""" + + secret_storage: bool = FieldInfo(alias="secretStorage") + """Whether secure key storage is available.""" + + verified: bool + """Whether this device is trusted for encrypted messages.""" + + recovery_code_generated_at: Optional[float] = FieldInfo(alias="recoveryCodeGeneratedAt", default=None) + """Unix timestamp for when the recovery key was created.""" + + +class AppStateMatrix(BaseModel): + """Signed-in account details. Omitted until sign-in is complete.""" + + device_id: str = FieldInfo(alias="deviceID") + """Current device ID.""" + + homeserver: str + """Beeper server URL for this account.""" + + user_id: str = FieldInfo(alias="userID") + """Signed-in Beeper user ID.""" + + +class AppStateVerificationError(BaseModel): + """Verification error details, if verification stopped.""" + + code: str + """Verification error code.""" + + reason: str + """User-facing verification error message.""" + + +class AppStateVerificationSas(BaseModel): + """Emoji or number comparison data for verification.""" + + decimals: str + """Number sequence to compare on both devices.""" + + emojis: str + """Emoji sequence to compare on both devices.""" + + +class AppStateVerification(BaseModel): + """Trusted-device verification progress.""" + + available_actions: List[ + Literal["create", "qr.scan", "accept", "cancel", "qr.confirmScanned", "sas.start", "sas.confirm"] + ] = FieldInfo(alias="availableActions") + """Verification actions that are valid for the current state.""" + + state: Literal["idle", "requested", "ready", "sas_ready", "qr_scanned", "done", "cancelled", "error"] + """Current trusted-device verification state.""" + + error: Optional[AppStateVerificationError] = None + """Verification error details, if verification stopped.""" + + from_: Optional[str] = FieldInfo(alias="from", default=None) + """User ID that started verification.""" + + from_device: Optional[str] = FieldInfo(alias="fromDevice", default=None) + """Device that started verification.""" + + other_device: Optional[str] = FieldInfo(alias="otherDevice", default=None) + """Other device participating in verification.""" + + qr_data: Optional[str] = FieldInfo(alias="qrData", default=None) + """QR code payload to display for verification.""" + + sas: Optional[AppStateVerificationSas] = None + """Emoji or number comparison data for verification.""" + + supports_sas: Optional[bool] = FieldInfo(alias="supportsSAS", default=None) + """Whether emoji comparison is available.""" + + supports_scan_qr_code: Optional[bool] = FieldInfo(alias="supportsScanQRCode", default=None) + """Whether QR code verification is available.""" + + verification_id: Optional[str] = FieldInfo(alias="verificationID", default=None) + """Verification ID to pass in verification action paths.""" + + +class AppState(BaseModel): + """Current onboarding state after the requested step.""" + + e2ee: AppStateE2ee + """Encrypted messaging setup status.""" + + state: Literal[ + "needs-login", + "initializing", + "needs-cross-signing-setup", + "needs-verification", + "needs-secrets", + "needs-first-sync", + "ready", + ] + """Current onboarding state for Beeper Desktop.""" + + matrix: Optional[AppStateMatrix] = None + """Signed-in account details. Omitted until sign-in is complete.""" + + verification: Optional[AppStateVerification] = None + """Trusted-device verification progress.""" + + +class SaConfirmResponse(BaseModel): + app_state: AppState = FieldInfo(alias="appState") + """Current onboarding state after the requested step.""" diff --git a/src/beeper_desktop_api/types/app/e2ee/verification/sa_start_response.py b/src/beeper_desktop_api/types/app/e2ee/verification/sa_start_response.py new file mode 100644 index 0000000..b68ed95 --- /dev/null +++ b/src/beeper_desktop_api/types/app/e2ee/verification/sa_start_response.py @@ -0,0 +1,170 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ....._models import BaseModel + +__all__ = [ + "SaStartResponse", + "AppState", + "AppStateE2ee", + "AppStateE2eeSecrets", + "AppStateMatrix", + "AppStateVerification", + "AppStateVerificationError", + "AppStateVerificationSas", +] + + +class AppStateE2eeSecrets(BaseModel): + """Encrypted messaging keys available on this device.""" + + master_key: bool = FieldInfo(alias="masterKey") + """Whether the account identity key is available.""" + + megolm_backup_key: bool = FieldInfo(alias="megolmBackupKey") + """Whether the encrypted message backup key is available.""" + + recovery_code: bool = FieldInfo(alias="recoveryCode") + """Whether a recovery key is available.""" + + self_signing_key: bool = FieldInfo(alias="selfSigningKey") + """Whether the device trust key is available.""" + + user_signing_key: bool = FieldInfo(alias="userSigningKey") + """Whether the user trust key is available.""" + + +class AppStateE2ee(BaseModel): + """Encrypted messaging setup status.""" + + cross_signing: bool = FieldInfo(alias="crossSigning") + """Whether this account can verify trusted devices.""" + + first_sync_done: bool = FieldInfo(alias="firstSyncDone") + """Whether the first encrypted message sync is complete.""" + + has_backed_up_code: bool = FieldInfo(alias="hasBackedUpCode") + """Whether the user confirmed that they saved their recovery key.""" + + initialized: bool + """Whether encrypted messaging setup has started.""" + + key_backup: bool = FieldInfo(alias="keyBackup") + """Whether encrypted message backup is available.""" + + secrets: AppStateE2eeSecrets + """Encrypted messaging keys available on this device.""" + + secret_storage: bool = FieldInfo(alias="secretStorage") + """Whether secure key storage is available.""" + + verified: bool + """Whether this device is trusted for encrypted messages.""" + + recovery_code_generated_at: Optional[float] = FieldInfo(alias="recoveryCodeGeneratedAt", default=None) + """Unix timestamp for when the recovery key was created.""" + + +class AppStateMatrix(BaseModel): + """Signed-in account details. Omitted until sign-in is complete.""" + + device_id: str = FieldInfo(alias="deviceID") + """Current device ID.""" + + homeserver: str + """Beeper server URL for this account.""" + + user_id: str = FieldInfo(alias="userID") + """Signed-in Beeper user ID.""" + + +class AppStateVerificationError(BaseModel): + """Verification error details, if verification stopped.""" + + code: str + """Verification error code.""" + + reason: str + """User-facing verification error message.""" + + +class AppStateVerificationSas(BaseModel): + """Emoji or number comparison data for verification.""" + + decimals: str + """Number sequence to compare on both devices.""" + + emojis: str + """Emoji sequence to compare on both devices.""" + + +class AppStateVerification(BaseModel): + """Trusted-device verification progress.""" + + available_actions: List[ + Literal["create", "qr.scan", "accept", "cancel", "qr.confirmScanned", "sas.start", "sas.confirm"] + ] = FieldInfo(alias="availableActions") + """Verification actions that are valid for the current state.""" + + state: Literal["idle", "requested", "ready", "sas_ready", "qr_scanned", "done", "cancelled", "error"] + """Current trusted-device verification state.""" + + error: Optional[AppStateVerificationError] = None + """Verification error details, if verification stopped.""" + + from_: Optional[str] = FieldInfo(alias="from", default=None) + """User ID that started verification.""" + + from_device: Optional[str] = FieldInfo(alias="fromDevice", default=None) + """Device that started verification.""" + + other_device: Optional[str] = FieldInfo(alias="otherDevice", default=None) + """Other device participating in verification.""" + + qr_data: Optional[str] = FieldInfo(alias="qrData", default=None) + """QR code payload to display for verification.""" + + sas: Optional[AppStateVerificationSas] = None + """Emoji or number comparison data for verification.""" + + supports_sas: Optional[bool] = FieldInfo(alias="supportsSAS", default=None) + """Whether emoji comparison is available.""" + + supports_scan_qr_code: Optional[bool] = FieldInfo(alias="supportsScanQRCode", default=None) + """Whether QR code verification is available.""" + + verification_id: Optional[str] = FieldInfo(alias="verificationID", default=None) + """Verification ID to pass in verification action paths.""" + + +class AppState(BaseModel): + """Current onboarding state after the requested step.""" + + e2ee: AppStateE2ee + """Encrypted messaging setup status.""" + + state: Literal[ + "needs-login", + "initializing", + "needs-cross-signing-setup", + "needs-verification", + "needs-secrets", + "needs-first-sync", + "ready", + ] + """Current onboarding state for Beeper Desktop.""" + + matrix: Optional[AppStateMatrix] = None + """Signed-in account details. Omitted until sign-in is complete.""" + + verification: Optional[AppStateVerification] = None + """Trusted-device verification progress.""" + + +class SaStartResponse(BaseModel): + app_state: AppState = FieldInfo(alias="appState") + """Current onboarding state after the requested step.""" diff --git a/src/beeper_desktop_api/types/app/e2ee/verification_accept_response.py b/src/beeper_desktop_api/types/app/e2ee/verification_accept_response.py new file mode 100644 index 0000000..5e3cc0e --- /dev/null +++ b/src/beeper_desktop_api/types/app/e2ee/verification_accept_response.py @@ -0,0 +1,170 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ...._models import BaseModel + +__all__ = [ + "VerificationAcceptResponse", + "AppState", + "AppStateE2ee", + "AppStateE2eeSecrets", + "AppStateMatrix", + "AppStateVerification", + "AppStateVerificationError", + "AppStateVerificationSas", +] + + +class AppStateE2eeSecrets(BaseModel): + """Encrypted messaging keys available on this device.""" + + master_key: bool = FieldInfo(alias="masterKey") + """Whether the account identity key is available.""" + + megolm_backup_key: bool = FieldInfo(alias="megolmBackupKey") + """Whether the encrypted message backup key is available.""" + + recovery_code: bool = FieldInfo(alias="recoveryCode") + """Whether a recovery key is available.""" + + self_signing_key: bool = FieldInfo(alias="selfSigningKey") + """Whether the device trust key is available.""" + + user_signing_key: bool = FieldInfo(alias="userSigningKey") + """Whether the user trust key is available.""" + + +class AppStateE2ee(BaseModel): + """Encrypted messaging setup status.""" + + cross_signing: bool = FieldInfo(alias="crossSigning") + """Whether this account can verify trusted devices.""" + + first_sync_done: bool = FieldInfo(alias="firstSyncDone") + """Whether the first encrypted message sync is complete.""" + + has_backed_up_code: bool = FieldInfo(alias="hasBackedUpCode") + """Whether the user confirmed that they saved their recovery key.""" + + initialized: bool + """Whether encrypted messaging setup has started.""" + + key_backup: bool = FieldInfo(alias="keyBackup") + """Whether encrypted message backup is available.""" + + secrets: AppStateE2eeSecrets + """Encrypted messaging keys available on this device.""" + + secret_storage: bool = FieldInfo(alias="secretStorage") + """Whether secure key storage is available.""" + + verified: bool + """Whether this device is trusted for encrypted messages.""" + + recovery_code_generated_at: Optional[float] = FieldInfo(alias="recoveryCodeGeneratedAt", default=None) + """Unix timestamp for when the recovery key was created.""" + + +class AppStateMatrix(BaseModel): + """Signed-in account details. Omitted until sign-in is complete.""" + + device_id: str = FieldInfo(alias="deviceID") + """Current device ID.""" + + homeserver: str + """Beeper server URL for this account.""" + + user_id: str = FieldInfo(alias="userID") + """Signed-in Beeper user ID.""" + + +class AppStateVerificationError(BaseModel): + """Verification error details, if verification stopped.""" + + code: str + """Verification error code.""" + + reason: str + """User-facing verification error message.""" + + +class AppStateVerificationSas(BaseModel): + """Emoji or number comparison data for verification.""" + + decimals: str + """Number sequence to compare on both devices.""" + + emojis: str + """Emoji sequence to compare on both devices.""" + + +class AppStateVerification(BaseModel): + """Trusted-device verification progress.""" + + available_actions: List[ + Literal["create", "qr.scan", "accept", "cancel", "qr.confirmScanned", "sas.start", "sas.confirm"] + ] = FieldInfo(alias="availableActions") + """Verification actions that are valid for the current state.""" + + state: Literal["idle", "requested", "ready", "sas_ready", "qr_scanned", "done", "cancelled", "error"] + """Current trusted-device verification state.""" + + error: Optional[AppStateVerificationError] = None + """Verification error details, if verification stopped.""" + + from_: Optional[str] = FieldInfo(alias="from", default=None) + """User ID that started verification.""" + + from_device: Optional[str] = FieldInfo(alias="fromDevice", default=None) + """Device that started verification.""" + + other_device: Optional[str] = FieldInfo(alias="otherDevice", default=None) + """Other device participating in verification.""" + + qr_data: Optional[str] = FieldInfo(alias="qrData", default=None) + """QR code payload to display for verification.""" + + sas: Optional[AppStateVerificationSas] = None + """Emoji or number comparison data for verification.""" + + supports_sas: Optional[bool] = FieldInfo(alias="supportsSAS", default=None) + """Whether emoji comparison is available.""" + + supports_scan_qr_code: Optional[bool] = FieldInfo(alias="supportsScanQRCode", default=None) + """Whether QR code verification is available.""" + + verification_id: Optional[str] = FieldInfo(alias="verificationID", default=None) + """Verification ID to pass in verification action paths.""" + + +class AppState(BaseModel): + """Current onboarding state after the requested step.""" + + e2ee: AppStateE2ee + """Encrypted messaging setup status.""" + + state: Literal[ + "needs-login", + "initializing", + "needs-cross-signing-setup", + "needs-verification", + "needs-secrets", + "needs-first-sync", + "ready", + ] + """Current onboarding state for Beeper Desktop.""" + + matrix: Optional[AppStateMatrix] = None + """Signed-in account details. Omitted until sign-in is complete.""" + + verification: Optional[AppStateVerification] = None + """Trusted-device verification progress.""" + + +class VerificationAcceptResponse(BaseModel): + app_state: AppState = FieldInfo(alias="appState") + """Current onboarding state after the requested step.""" diff --git a/src/beeper_desktop_api/types/app/e2ee/verification_cancel_params.py b/src/beeper_desktop_api/types/app/e2ee/verification_cancel_params.py new file mode 100644 index 0000000..d954b97 --- /dev/null +++ b/src/beeper_desktop_api/types/app/e2ee/verification_cancel_params.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import TypedDict + +__all__ = ["VerificationCancelParams"] + + +class VerificationCancelParams(TypedDict, total=False): + code: str + """Optional cancellation code.""" + + reason: str + """Optional user-facing cancellation reason.""" diff --git a/src/beeper_desktop_api/types/app/e2ee/verification_cancel_response.py b/src/beeper_desktop_api/types/app/e2ee/verification_cancel_response.py new file mode 100644 index 0000000..4f19689 --- /dev/null +++ b/src/beeper_desktop_api/types/app/e2ee/verification_cancel_response.py @@ -0,0 +1,170 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ...._models import BaseModel + +__all__ = [ + "VerificationCancelResponse", + "AppState", + "AppStateE2ee", + "AppStateE2eeSecrets", + "AppStateMatrix", + "AppStateVerification", + "AppStateVerificationError", + "AppStateVerificationSas", +] + + +class AppStateE2eeSecrets(BaseModel): + """Encrypted messaging keys available on this device.""" + + master_key: bool = FieldInfo(alias="masterKey") + """Whether the account identity key is available.""" + + megolm_backup_key: bool = FieldInfo(alias="megolmBackupKey") + """Whether the encrypted message backup key is available.""" + + recovery_code: bool = FieldInfo(alias="recoveryCode") + """Whether a recovery key is available.""" + + self_signing_key: bool = FieldInfo(alias="selfSigningKey") + """Whether the device trust key is available.""" + + user_signing_key: bool = FieldInfo(alias="userSigningKey") + """Whether the user trust key is available.""" + + +class AppStateE2ee(BaseModel): + """Encrypted messaging setup status.""" + + cross_signing: bool = FieldInfo(alias="crossSigning") + """Whether this account can verify trusted devices.""" + + first_sync_done: bool = FieldInfo(alias="firstSyncDone") + """Whether the first encrypted message sync is complete.""" + + has_backed_up_code: bool = FieldInfo(alias="hasBackedUpCode") + """Whether the user confirmed that they saved their recovery key.""" + + initialized: bool + """Whether encrypted messaging setup has started.""" + + key_backup: bool = FieldInfo(alias="keyBackup") + """Whether encrypted message backup is available.""" + + secrets: AppStateE2eeSecrets + """Encrypted messaging keys available on this device.""" + + secret_storage: bool = FieldInfo(alias="secretStorage") + """Whether secure key storage is available.""" + + verified: bool + """Whether this device is trusted for encrypted messages.""" + + recovery_code_generated_at: Optional[float] = FieldInfo(alias="recoveryCodeGeneratedAt", default=None) + """Unix timestamp for when the recovery key was created.""" + + +class AppStateMatrix(BaseModel): + """Signed-in account details. Omitted until sign-in is complete.""" + + device_id: str = FieldInfo(alias="deviceID") + """Current device ID.""" + + homeserver: str + """Beeper server URL for this account.""" + + user_id: str = FieldInfo(alias="userID") + """Signed-in Beeper user ID.""" + + +class AppStateVerificationError(BaseModel): + """Verification error details, if verification stopped.""" + + code: str + """Verification error code.""" + + reason: str + """User-facing verification error message.""" + + +class AppStateVerificationSas(BaseModel): + """Emoji or number comparison data for verification.""" + + decimals: str + """Number sequence to compare on both devices.""" + + emojis: str + """Emoji sequence to compare on both devices.""" + + +class AppStateVerification(BaseModel): + """Trusted-device verification progress.""" + + available_actions: List[ + Literal["create", "qr.scan", "accept", "cancel", "qr.confirmScanned", "sas.start", "sas.confirm"] + ] = FieldInfo(alias="availableActions") + """Verification actions that are valid for the current state.""" + + state: Literal["idle", "requested", "ready", "sas_ready", "qr_scanned", "done", "cancelled", "error"] + """Current trusted-device verification state.""" + + error: Optional[AppStateVerificationError] = None + """Verification error details, if verification stopped.""" + + from_: Optional[str] = FieldInfo(alias="from", default=None) + """User ID that started verification.""" + + from_device: Optional[str] = FieldInfo(alias="fromDevice", default=None) + """Device that started verification.""" + + other_device: Optional[str] = FieldInfo(alias="otherDevice", default=None) + """Other device participating in verification.""" + + qr_data: Optional[str] = FieldInfo(alias="qrData", default=None) + """QR code payload to display for verification.""" + + sas: Optional[AppStateVerificationSas] = None + """Emoji or number comparison data for verification.""" + + supports_sas: Optional[bool] = FieldInfo(alias="supportsSAS", default=None) + """Whether emoji comparison is available.""" + + supports_scan_qr_code: Optional[bool] = FieldInfo(alias="supportsScanQRCode", default=None) + """Whether QR code verification is available.""" + + verification_id: Optional[str] = FieldInfo(alias="verificationID", default=None) + """Verification ID to pass in verification action paths.""" + + +class AppState(BaseModel): + """Current onboarding state after the requested step.""" + + e2ee: AppStateE2ee + """Encrypted messaging setup status.""" + + state: Literal[ + "needs-login", + "initializing", + "needs-cross-signing-setup", + "needs-verification", + "needs-secrets", + "needs-first-sync", + "ready", + ] + """Current onboarding state for Beeper Desktop.""" + + matrix: Optional[AppStateMatrix] = None + """Signed-in account details. Omitted until sign-in is complete.""" + + verification: Optional[AppStateVerification] = None + """Trusted-device verification progress.""" + + +class VerificationCancelResponse(BaseModel): + app_state: AppState = FieldInfo(alias="appState") + """Current onboarding state after the requested step.""" diff --git a/src/beeper_desktop_api/types/app/e2ee/verification_create_params.py b/src/beeper_desktop_api/types/app/e2ee/verification_create_params.py new file mode 100644 index 0000000..c46feac --- /dev/null +++ b/src/beeper_desktop_api/types/app/e2ee/verification_create_params.py @@ -0,0 +1,14 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Annotated, TypedDict + +from ...._utils import PropertyInfo + +__all__ = ["VerificationCreateParams"] + + +class VerificationCreateParams(TypedDict, total=False): + user_id: Annotated[str, PropertyInfo(alias="userID")] + """User ID to verify. Defaults to the signed-in user.""" diff --git a/src/beeper_desktop_api/types/app/e2ee/verification_create_response.py b/src/beeper_desktop_api/types/app/e2ee/verification_create_response.py new file mode 100644 index 0000000..d5ccc58 --- /dev/null +++ b/src/beeper_desktop_api/types/app/e2ee/verification_create_response.py @@ -0,0 +1,173 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ...._models import BaseModel + +__all__ = [ + "VerificationCreateResponse", + "AppState", + "AppStateE2ee", + "AppStateE2eeSecrets", + "AppStateMatrix", + "AppStateVerification", + "AppStateVerificationError", + "AppStateVerificationSas", +] + + +class AppStateE2eeSecrets(BaseModel): + """Encrypted messaging keys available on this device.""" + + master_key: bool = FieldInfo(alias="masterKey") + """Whether the account identity key is available.""" + + megolm_backup_key: bool = FieldInfo(alias="megolmBackupKey") + """Whether the encrypted message backup key is available.""" + + recovery_code: bool = FieldInfo(alias="recoveryCode") + """Whether a recovery key is available.""" + + self_signing_key: bool = FieldInfo(alias="selfSigningKey") + """Whether the device trust key is available.""" + + user_signing_key: bool = FieldInfo(alias="userSigningKey") + """Whether the user trust key is available.""" + + +class AppStateE2ee(BaseModel): + """Encrypted messaging setup status.""" + + cross_signing: bool = FieldInfo(alias="crossSigning") + """Whether this account can verify trusted devices.""" + + first_sync_done: bool = FieldInfo(alias="firstSyncDone") + """Whether the first encrypted message sync is complete.""" + + has_backed_up_code: bool = FieldInfo(alias="hasBackedUpCode") + """Whether the user confirmed that they saved their recovery key.""" + + initialized: bool + """Whether encrypted messaging setup has started.""" + + key_backup: bool = FieldInfo(alias="keyBackup") + """Whether encrypted message backup is available.""" + + secrets: AppStateE2eeSecrets + """Encrypted messaging keys available on this device.""" + + secret_storage: bool = FieldInfo(alias="secretStorage") + """Whether secure key storage is available.""" + + verified: bool + """Whether this device is trusted for encrypted messages.""" + + recovery_code_generated_at: Optional[float] = FieldInfo(alias="recoveryCodeGeneratedAt", default=None) + """Unix timestamp for when the recovery key was created.""" + + +class AppStateMatrix(BaseModel): + """Signed-in account details. Omitted until sign-in is complete.""" + + device_id: str = FieldInfo(alias="deviceID") + """Current device ID.""" + + homeserver: str + """Beeper server URL for this account.""" + + user_id: str = FieldInfo(alias="userID") + """Signed-in Beeper user ID.""" + + +class AppStateVerificationError(BaseModel): + """Verification error details, if verification stopped.""" + + code: str + """Verification error code.""" + + reason: str + """User-facing verification error message.""" + + +class AppStateVerificationSas(BaseModel): + """Emoji or number comparison data for verification.""" + + decimals: str + """Number sequence to compare on both devices.""" + + emojis: str + """Emoji sequence to compare on both devices.""" + + +class AppStateVerification(BaseModel): + """Trusted-device verification progress.""" + + available_actions: List[ + Literal["create", "qr.scan", "accept", "cancel", "qr.confirmScanned", "sas.start", "sas.confirm"] + ] = FieldInfo(alias="availableActions") + """Verification actions that are valid for the current state.""" + + state: Literal["idle", "requested", "ready", "sas_ready", "qr_scanned", "done", "cancelled", "error"] + """Current trusted-device verification state.""" + + error: Optional[AppStateVerificationError] = None + """Verification error details, if verification stopped.""" + + from_: Optional[str] = FieldInfo(alias="from", default=None) + """User ID that started verification.""" + + from_device: Optional[str] = FieldInfo(alias="fromDevice", default=None) + """Device that started verification.""" + + other_device: Optional[str] = FieldInfo(alias="otherDevice", default=None) + """Other device participating in verification.""" + + qr_data: Optional[str] = FieldInfo(alias="qrData", default=None) + """QR code payload to display for verification.""" + + sas: Optional[AppStateVerificationSas] = None + """Emoji or number comparison data for verification.""" + + supports_sas: Optional[bool] = FieldInfo(alias="supportsSAS", default=None) + """Whether emoji comparison is available.""" + + supports_scan_qr_code: Optional[bool] = FieldInfo(alias="supportsScanQRCode", default=None) + """Whether QR code verification is available.""" + + verification_id: Optional[str] = FieldInfo(alias="verificationID", default=None) + """Verification ID to pass in verification action paths.""" + + +class AppState(BaseModel): + """Current onboarding state after starting verification.""" + + e2ee: AppStateE2ee + """Encrypted messaging setup status.""" + + state: Literal[ + "needs-login", + "initializing", + "needs-cross-signing-setup", + "needs-verification", + "needs-secrets", + "needs-first-sync", + "ready", + ] + """Current onboarding state for Beeper Desktop.""" + + matrix: Optional[AppStateMatrix] = None + """Signed-in account details. Omitted until sign-in is complete.""" + + verification: Optional[AppStateVerification] = None + """Trusted-device verification progress.""" + + +class VerificationCreateResponse(BaseModel): + app_state: AppState = FieldInfo(alias="appState") + """Current onboarding state after starting verification.""" + + verification_id: str = FieldInfo(alias="verificationID") + """Verification ID to pass in verification action paths.""" diff --git a/src/beeper_desktop_api/types/app/login_email_params.py b/src/beeper_desktop_api/types/app/login_email_params.py new file mode 100644 index 0000000..bbf1d19 --- /dev/null +++ b/src/beeper_desktop_api/types/app/login_email_params.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["LoginEmailParams"] + + +class LoginEmailParams(TypedDict, total=False): + email: Required[str] + """Email address to send the sign-in code to.""" + + request: Required[str] + """Login request ID returned by the start step.""" diff --git a/src/beeper_desktop_api/types/app/login_register_params.py b/src/beeper_desktop_api/types/app/login_register_params.py new file mode 100644 index 0000000..f6ea523 --- /dev/null +++ b/src/beeper_desktop_api/types/app/login_register_params.py @@ -0,0 +1,26 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["LoginRegisterParams"] + + +class LoginRegisterParams(TypedDict, total=False): + accept_terms: Required[Annotated[Literal[True], PropertyInfo(alias="acceptTerms")]] + """ + Confirms that the user accepted the Terms of Use and acknowledged the Privacy + Policy. + """ + + lead_token: Required[Annotated[str, PropertyInfo(alias="leadToken")]] + """Registration token returned by Beeper.""" + + request: Required[str] + """Login request ID returned by the start step.""" + + username: Required[str] + """Username selected by the user.""" diff --git a/src/beeper_desktop_api/types/app/login_register_response.py b/src/beeper_desktop_api/types/app/login_register_response.py new file mode 100644 index 0000000..1296355 --- /dev/null +++ b/src/beeper_desktop_api/types/app/login_register_response.py @@ -0,0 +1,207 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = [ + "LoginRegisterResponse", + "AppState", + "AppStateE2ee", + "AppStateE2eeSecrets", + "AppStateMatrix", + "AppStateVerification", + "AppStateVerificationError", + "AppStateVerificationSas", + "DesktopAPI", + "Matrix", +] + + +class AppStateE2eeSecrets(BaseModel): + """Encrypted messaging keys available on this device.""" + + master_key: bool = FieldInfo(alias="masterKey") + """Whether the account identity key is available.""" + + megolm_backup_key: bool = FieldInfo(alias="megolmBackupKey") + """Whether the encrypted message backup key is available.""" + + recovery_code: bool = FieldInfo(alias="recoveryCode") + """Whether a recovery key is available.""" + + self_signing_key: bool = FieldInfo(alias="selfSigningKey") + """Whether the device trust key is available.""" + + user_signing_key: bool = FieldInfo(alias="userSigningKey") + """Whether the user trust key is available.""" + + +class AppStateE2ee(BaseModel): + """Encrypted messaging setup status.""" + + cross_signing: bool = FieldInfo(alias="crossSigning") + """Whether this account can verify trusted devices.""" + + first_sync_done: bool = FieldInfo(alias="firstSyncDone") + """Whether the first encrypted message sync is complete.""" + + has_backed_up_code: bool = FieldInfo(alias="hasBackedUpCode") + """Whether the user confirmed that they saved their recovery key.""" + + initialized: bool + """Whether encrypted messaging setup has started.""" + + key_backup: bool = FieldInfo(alias="keyBackup") + """Whether encrypted message backup is available.""" + + secrets: AppStateE2eeSecrets + """Encrypted messaging keys available on this device.""" + + secret_storage: bool = FieldInfo(alias="secretStorage") + """Whether secure key storage is available.""" + + verified: bool + """Whether this device is trusted for encrypted messages.""" + + recovery_code_generated_at: Optional[float] = FieldInfo(alias="recoveryCodeGeneratedAt", default=None) + """Unix timestamp for when the recovery key was created.""" + + +class AppStateMatrix(BaseModel): + """Signed-in account details. Omitted until sign-in is complete.""" + + device_id: str = FieldInfo(alias="deviceID") + """Current device ID.""" + + homeserver: str + """Beeper server URL for this account.""" + + user_id: str = FieldInfo(alias="userID") + """Signed-in Beeper user ID.""" + + +class AppStateVerificationError(BaseModel): + """Verification error details, if verification stopped.""" + + code: str + """Verification error code.""" + + reason: str + """User-facing verification error message.""" + + +class AppStateVerificationSas(BaseModel): + """Emoji or number comparison data for verification.""" + + decimals: str + """Number sequence to compare on both devices.""" + + emojis: str + """Emoji sequence to compare on both devices.""" + + +class AppStateVerification(BaseModel): + """Trusted-device verification progress.""" + + available_actions: List[ + Literal["create", "qr.scan", "accept", "cancel", "qr.confirmScanned", "sas.start", "sas.confirm"] + ] = FieldInfo(alias="availableActions") + """Verification actions that are valid for the current state.""" + + state: Literal["idle", "requested", "ready", "sas_ready", "qr_scanned", "done", "cancelled", "error"] + """Current trusted-device verification state.""" + + error: Optional[AppStateVerificationError] = None + """Verification error details, if verification stopped.""" + + from_: Optional[str] = FieldInfo(alias="from", default=None) + """User ID that started verification.""" + + from_device: Optional[str] = FieldInfo(alias="fromDevice", default=None) + """Device that started verification.""" + + other_device: Optional[str] = FieldInfo(alias="otherDevice", default=None) + """Other device participating in verification.""" + + qr_data: Optional[str] = FieldInfo(alias="qrData", default=None) + """QR code payload to display for verification.""" + + sas: Optional[AppStateVerificationSas] = None + """Emoji or number comparison data for verification.""" + + supports_sas: Optional[bool] = FieldInfo(alias="supportsSAS", default=None) + """Whether emoji comparison is available.""" + + supports_scan_qr_code: Optional[bool] = FieldInfo(alias="supportsScanQRCode", default=None) + """Whether QR code verification is available.""" + + verification_id: Optional[str] = FieldInfo(alias="verificationID", default=None) + """Verification ID to pass in verification action paths.""" + + +class AppState(BaseModel): + """Current onboarding state after sign-in.""" + + e2ee: AppStateE2ee + """Encrypted messaging setup status.""" + + state: Literal[ + "needs-login", + "initializing", + "needs-cross-signing-setup", + "needs-verification", + "needs-secrets", + "needs-first-sync", + "ready", + ] + """Current onboarding state for Beeper Desktop.""" + + matrix: Optional[AppStateMatrix] = None + """Signed-in account details. Omitted until sign-in is complete.""" + + verification: Optional[AppStateVerification] = None + """Trusted-device verification progress.""" + + +class DesktopAPI(BaseModel): + """Desktop API credentials for the signed-in app session.""" + + access_token: str = FieldInfo(alias="accessToken") + """Desktop API access token for this app session.""" + + scope: Literal["read write"] + """Granted Desktop API scopes.""" + + token_type: Literal["Bearer"] = FieldInfo(alias="tokenType") + """Access token type.""" + + +class Matrix(BaseModel): + """Account credentials for first-party app setup.""" + + access_token: str = FieldInfo(alias="accessToken") + """Account access token. Returned once for first-party app setup.""" + + device_id: str = FieldInfo(alias="deviceID") + """Current device ID.""" + + homeserver: str + """Beeper server URL for this account.""" + + user_id: str = FieldInfo(alias="userID") + """Signed-in Beeper user ID.""" + + +class LoginRegisterResponse(BaseModel): + app_state: AppState = FieldInfo(alias="appState") + """Current onboarding state after sign-in.""" + + desktop_api: DesktopAPI = FieldInfo(alias="desktopAPI") + """Desktop API credentials for the signed-in app session.""" + + matrix: Matrix + """Account credentials for first-party app setup.""" diff --git a/src/beeper_desktop_api/types/app/login_response_params.py b/src/beeper_desktop_api/types/app/login_response_params.py new file mode 100644 index 0000000..f218f96 --- /dev/null +++ b/src/beeper_desktop_api/types/app/login_response_params.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["LoginResponseParams"] + + +class LoginResponseParams(TypedDict, total=False): + request: Required[str] + """Login request ID returned by the start step.""" + + response: Required[str] + """Sign-in code from the user email.""" diff --git a/src/beeper_desktop_api/types/app/login_response_response.py b/src/beeper_desktop_api/types/app/login_response_response.py new file mode 100644 index 0000000..e28b77d --- /dev/null +++ b/src/beeper_desktop_api/types/app/login_response_response.py @@ -0,0 +1,246 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Union, Optional +from typing_extensions import Literal, TypeAlias + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = [ + "LoginResponseResponse", + "UnionMember0", + "UnionMember0AppState", + "UnionMember0AppStateE2ee", + "UnionMember0AppStateE2eeSecrets", + "UnionMember0AppStateMatrix", + "UnionMember0AppStateVerification", + "UnionMember0AppStateVerificationError", + "UnionMember0AppStateVerificationSas", + "UnionMember0DesktopAPI", + "UnionMember0Matrix", + "UnionMember1", + "UnionMember1Copy", +] + + +class UnionMember0AppStateE2eeSecrets(BaseModel): + """Encrypted messaging keys available on this device.""" + + master_key: bool = FieldInfo(alias="masterKey") + """Whether the account identity key is available.""" + + megolm_backup_key: bool = FieldInfo(alias="megolmBackupKey") + """Whether the encrypted message backup key is available.""" + + recovery_code: bool = FieldInfo(alias="recoveryCode") + """Whether a recovery key is available.""" + + self_signing_key: bool = FieldInfo(alias="selfSigningKey") + """Whether the device trust key is available.""" + + user_signing_key: bool = FieldInfo(alias="userSigningKey") + """Whether the user trust key is available.""" + + +class UnionMember0AppStateE2ee(BaseModel): + """Encrypted messaging setup status.""" + + cross_signing: bool = FieldInfo(alias="crossSigning") + """Whether this account can verify trusted devices.""" + + first_sync_done: bool = FieldInfo(alias="firstSyncDone") + """Whether the first encrypted message sync is complete.""" + + has_backed_up_code: bool = FieldInfo(alias="hasBackedUpCode") + """Whether the user confirmed that they saved their recovery key.""" + + initialized: bool + """Whether encrypted messaging setup has started.""" + + key_backup: bool = FieldInfo(alias="keyBackup") + """Whether encrypted message backup is available.""" + + secrets: UnionMember0AppStateE2eeSecrets + """Encrypted messaging keys available on this device.""" + + secret_storage: bool = FieldInfo(alias="secretStorage") + """Whether secure key storage is available.""" + + verified: bool + """Whether this device is trusted for encrypted messages.""" + + recovery_code_generated_at: Optional[float] = FieldInfo(alias="recoveryCodeGeneratedAt", default=None) + """Unix timestamp for when the recovery key was created.""" + + +class UnionMember0AppStateMatrix(BaseModel): + """Signed-in account details. Omitted until sign-in is complete.""" + + device_id: str = FieldInfo(alias="deviceID") + """Current device ID.""" + + homeserver: str + """Beeper server URL for this account.""" + + user_id: str = FieldInfo(alias="userID") + """Signed-in Beeper user ID.""" + + +class UnionMember0AppStateVerificationError(BaseModel): + """Verification error details, if verification stopped.""" + + code: str + """Verification error code.""" + + reason: str + """User-facing verification error message.""" + + +class UnionMember0AppStateVerificationSas(BaseModel): + """Emoji or number comparison data for verification.""" + + decimals: str + """Number sequence to compare on both devices.""" + + emojis: str + """Emoji sequence to compare on both devices.""" + + +class UnionMember0AppStateVerification(BaseModel): + """Trusted-device verification progress.""" + + available_actions: List[ + Literal["create", "qr.scan", "accept", "cancel", "qr.confirmScanned", "sas.start", "sas.confirm"] + ] = FieldInfo(alias="availableActions") + """Verification actions that are valid for the current state.""" + + state: Literal["idle", "requested", "ready", "sas_ready", "qr_scanned", "done", "cancelled", "error"] + """Current trusted-device verification state.""" + + error: Optional[UnionMember0AppStateVerificationError] = None + """Verification error details, if verification stopped.""" + + from_: Optional[str] = FieldInfo(alias="from", default=None) + """User ID that started verification.""" + + from_device: Optional[str] = FieldInfo(alias="fromDevice", default=None) + """Device that started verification.""" + + other_device: Optional[str] = FieldInfo(alias="otherDevice", default=None) + """Other device participating in verification.""" + + qr_data: Optional[str] = FieldInfo(alias="qrData", default=None) + """QR code payload to display for verification.""" + + sas: Optional[UnionMember0AppStateVerificationSas] = None + """Emoji or number comparison data for verification.""" + + supports_sas: Optional[bool] = FieldInfo(alias="supportsSAS", default=None) + """Whether emoji comparison is available.""" + + supports_scan_qr_code: Optional[bool] = FieldInfo(alias="supportsScanQRCode", default=None) + """Whether QR code verification is available.""" + + verification_id: Optional[str] = FieldInfo(alias="verificationID", default=None) + """Verification ID to pass in verification action paths.""" + + +class UnionMember0AppState(BaseModel): + """Current onboarding state after sign-in.""" + + e2ee: UnionMember0AppStateE2ee + """Encrypted messaging setup status.""" + + state: Literal[ + "needs-login", + "initializing", + "needs-cross-signing-setup", + "needs-verification", + "needs-secrets", + "needs-first-sync", + "ready", + ] + """Current onboarding state for Beeper Desktop.""" + + matrix: Optional[UnionMember0AppStateMatrix] = None + """Signed-in account details. Omitted until sign-in is complete.""" + + verification: Optional[UnionMember0AppStateVerification] = None + """Trusted-device verification progress.""" + + +class UnionMember0DesktopAPI(BaseModel): + """Desktop API credentials for the signed-in app session.""" + + access_token: str = FieldInfo(alias="accessToken") + """Desktop API access token for this app session.""" + + scope: Literal["read write"] + """Granted Desktop API scopes.""" + + token_type: Literal["Bearer"] = FieldInfo(alias="tokenType") + """Access token type.""" + + +class UnionMember0Matrix(BaseModel): + """Account credentials for first-party app setup.""" + + access_token: str = FieldInfo(alias="accessToken") + """Account access token. Returned once for first-party app setup.""" + + device_id: str = FieldInfo(alias="deviceID") + """Current device ID.""" + + homeserver: str + """Beeper server URL for this account.""" + + user_id: str = FieldInfo(alias="userID") + """Signed-in Beeper user ID.""" + + +class UnionMember0(BaseModel): + app_state: UnionMember0AppState = FieldInfo(alias="appState") + """Current onboarding state after sign-in.""" + + desktop_api: UnionMember0DesktopAPI = FieldInfo(alias="desktopAPI") + """Desktop API credentials for the signed-in app session.""" + + matrix: UnionMember0Matrix + """Account credentials for first-party app setup.""" + + +class UnionMember1Copy(BaseModel): + """Copy to display during account creation.""" + + submit: Literal["Continue"] + """Submit button label.""" + + terms: Literal["By continuing, you agree to the Terms of Use and acknowledge the Privacy Policy."] + """Terms and privacy notice to show before account creation.""" + + title: Literal["Choose your username"] + """Title for the username step.""" + + username_placeholder: Literal["Username"] = FieldInfo(alias="usernamePlaceholder") + """Placeholder for the username field.""" + + +class UnionMember1(BaseModel): + copy_: UnionMember1Copy = FieldInfo(alias="copy") + """Copy to display during account creation.""" + + lead_token: str = FieldInfo(alias="leadToken") + """Registration token returned by Beeper.""" + + registration_required: Literal[True] = FieldInfo(alias="registrationRequired") + """Indicates that the user needs to create a Beeper account.""" + + request: str + """Login request ID to use when creating the account.""" + + username_suggestions: Optional[List[str]] = FieldInfo(alias="usernameSuggestions", default=None) + """Suggested usernames for the new account.""" + + +LoginResponseResponse: TypeAlias = Union[UnionMember0, UnionMember1] diff --git a/src/beeper_desktop_api/types/app/login_start_response.py b/src/beeper_desktop_api/types/app/login_start_response.py new file mode 100644 index 0000000..d108b0d --- /dev/null +++ b/src/beeper_desktop_api/types/app/login_start_response.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List + +from ..._models import BaseModel + +__all__ = ["LoginStartResponse"] + + +class LoginStartResponse(BaseModel): + request: str + """Login request ID to use in the next sign-in step.""" + + type: List[str] + """Available sign-in methods for this request.""" diff --git a/src/beeper_desktop_api/types/app_status_response.py b/src/beeper_desktop_api/types/app_status_response.py new file mode 100644 index 0000000..dbc8499 --- /dev/null +++ b/src/beeper_desktop_api/types/app_status_response.py @@ -0,0 +1,154 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from .._models import BaseModel + +__all__ = ["AppStatusResponse", "E2ee", "E2eeSecrets", "Matrix", "Verification", "VerificationError", "VerificationSas"] + + +class E2eeSecrets(BaseModel): + """Encrypted messaging keys available on this device.""" + + master_key: bool = FieldInfo(alias="masterKey") + """Whether the account identity key is available.""" + + megolm_backup_key: bool = FieldInfo(alias="megolmBackupKey") + """Whether the encrypted message backup key is available.""" + + recovery_code: bool = FieldInfo(alias="recoveryCode") + """Whether a recovery key is available.""" + + self_signing_key: bool = FieldInfo(alias="selfSigningKey") + """Whether the device trust key is available.""" + + user_signing_key: bool = FieldInfo(alias="userSigningKey") + """Whether the user trust key is available.""" + + +class E2ee(BaseModel): + """Encrypted messaging setup status.""" + + cross_signing: bool = FieldInfo(alias="crossSigning") + """Whether this account can verify trusted devices.""" + + first_sync_done: bool = FieldInfo(alias="firstSyncDone") + """Whether the first encrypted message sync is complete.""" + + has_backed_up_code: bool = FieldInfo(alias="hasBackedUpCode") + """Whether the user confirmed that they saved their recovery key.""" + + initialized: bool + """Whether encrypted messaging setup has started.""" + + key_backup: bool = FieldInfo(alias="keyBackup") + """Whether encrypted message backup is available.""" + + secrets: E2eeSecrets + """Encrypted messaging keys available on this device.""" + + secret_storage: bool = FieldInfo(alias="secretStorage") + """Whether secure key storage is available.""" + + verified: bool + """Whether this device is trusted for encrypted messages.""" + + recovery_code_generated_at: Optional[float] = FieldInfo(alias="recoveryCodeGeneratedAt", default=None) + """Unix timestamp for when the recovery key was created.""" + + +class Matrix(BaseModel): + """Signed-in account details. Omitted until sign-in is complete.""" + + device_id: str = FieldInfo(alias="deviceID") + """Current device ID.""" + + homeserver: str + """Beeper server URL for this account.""" + + user_id: str = FieldInfo(alias="userID") + """Signed-in Beeper user ID.""" + + +class VerificationError(BaseModel): + """Verification error details, if verification stopped.""" + + code: str + """Verification error code.""" + + reason: str + """User-facing verification error message.""" + + +class VerificationSas(BaseModel): + """Emoji or number comparison data for verification.""" + + decimals: str + """Number sequence to compare on both devices.""" + + emojis: str + """Emoji sequence to compare on both devices.""" + + +class Verification(BaseModel): + """Trusted-device verification progress.""" + + available_actions: List[ + Literal["create", "qr.scan", "accept", "cancel", "qr.confirmScanned", "sas.start", "sas.confirm"] + ] = FieldInfo(alias="availableActions") + """Verification actions that are valid for the current state.""" + + state: Literal["idle", "requested", "ready", "sas_ready", "qr_scanned", "done", "cancelled", "error"] + """Current trusted-device verification state.""" + + error: Optional[VerificationError] = None + """Verification error details, if verification stopped.""" + + from_: Optional[str] = FieldInfo(alias="from", default=None) + """User ID that started verification.""" + + from_device: Optional[str] = FieldInfo(alias="fromDevice", default=None) + """Device that started verification.""" + + other_device: Optional[str] = FieldInfo(alias="otherDevice", default=None) + """Other device participating in verification.""" + + qr_data: Optional[str] = FieldInfo(alias="qrData", default=None) + """QR code payload to display for verification.""" + + sas: Optional[VerificationSas] = None + """Emoji or number comparison data for verification.""" + + supports_sas: Optional[bool] = FieldInfo(alias="supportsSAS", default=None) + """Whether emoji comparison is available.""" + + supports_scan_qr_code: Optional[bool] = FieldInfo(alias="supportsScanQRCode", default=None) + """Whether QR code verification is available.""" + + verification_id: Optional[str] = FieldInfo(alias="verificationID", default=None) + """Verification ID to pass in verification action paths.""" + + +class AppStatusResponse(BaseModel): + e2ee: E2ee + """Encrypted messaging setup status.""" + + state: Literal[ + "needs-login", + "initializing", + "needs-cross-signing-setup", + "needs-verification", + "needs-secrets", + "needs-first-sync", + "ready", + ] + """Current onboarding state for Beeper Desktop.""" + + matrix: Optional[Matrix] = None + """Signed-in account details. Omitted until sign-in is complete.""" + + verification: Optional[Verification] = None + """Trusted-device verification progress.""" diff --git a/src/beeper_desktop_api/types/bridge_availability.py b/src/beeper_desktop_api/types/bridge_availability.py new file mode 100644 index 0000000..abf7746 --- /dev/null +++ b/src/beeper_desktop_api/types/bridge_availability.py @@ -0,0 +1,63 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from .account import Account +from .._models import BaseModel + +__all__ = ["BridgeAvailability", "Bridge"] + + +class Bridge(BaseModel): + """Bridge metadata for the account. Available in Beeper Desktop v4.2.785+.""" + + id: str + """Bridge instance identifier. + + Matrix and cloud bridges often use the bridge type (for example matrix or + discordgo); local bridges use a local bridge ID (for example local-whatsapp). + Available in Beeper Desktop v4.2.785+. + """ + + provider: Literal["cloud", "self-hosted", "local", "platform-sdk"] + """Bridge provider for the account. Available in Beeper Desktop v4.2.785+.""" + + type: str + """Bridge type, such as matrix, discordgo, slackgo, whatsapp, telegram, or twitter. + + Available in Beeper Desktop v4.2.785+. + """ + + +class BridgeAvailability(BaseModel): + """Bridge-backed account type that can be shown in add-account flows.""" + + accounts: List[Account] + """Connected accounts for this bridge. + + Uses the same Account schema as GET /v1/accounts. + """ + + active_account_count: int = FieldInfo(alias="activeAccountCount") + """Number of active accounts for this network on this device.""" + + bridge: Bridge + """Bridge metadata for the account. Available in Beeper Desktop v4.2.785+.""" + + display_name: str = FieldInfo(alias="displayName") + """Human-friendly account type name shown in Beeper Desktop.""" + + login_mode: str = FieldInfo(alias="loginMode") + """Login mode used by Beeper Desktop for this bridge.""" + + status: Literal["available", "connected", "limit_reached", "temporarily_unavailable"] + """Whether this bridge can currently be used to add an account.""" + + network: Optional[str] = None + """Network grouping used for account counts and limits.""" + + status_text: Optional[str] = FieldInfo(alias="statusText", default=None) + """Human-friendly status text matching Beeper Desktop account management language.""" diff --git a/src/beeper_desktop_api/types/bridge_list_response.py b/src/beeper_desktop_api/types/bridge_list_response.py new file mode 100644 index 0000000..fc09661 --- /dev/null +++ b/src/beeper_desktop_api/types/bridge_list_response.py @@ -0,0 +1,14 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List + +from .._models import BaseModel +from .bridge_availability import BridgeAvailability + +__all__ = ["BridgeListResponse"] + + +class BridgeListResponse(BaseModel): + """Bridge-backed account types and their connected accounts.""" + + items: List[BridgeAvailability] diff --git a/src/beeper_desktop_api/types/matrix/__init__.py b/src/beeper_desktop_api/types/matrix/__init__.py new file mode 100644 index 0000000..1dfecfe --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/__init__.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .room_join_params import RoomJoinParams as RoomJoinParams +from .room_leave_params import RoomLeaveParams as RoomLeaveParams +from .room_create_params import RoomCreateParams as RoomCreateParams +from .room_join_response import RoomJoinResponse as RoomJoinResponse +from .room_create_response import RoomCreateResponse as RoomCreateResponse +from .user_retrieve_profile_response import UserRetrieveProfileResponse as UserRetrieveProfileResponse diff --git a/src/beeper_desktop_api/types/matrix/bridges/__init__.py b/src/beeper_desktop_api/types/matrix/bridges/__init__.py new file mode 100644 index 0000000..ff6da5f --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/bridges/__init__.py @@ -0,0 +1,25 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .user_search_params import UserSearchParams as UserSearchParams +from .contact_list_params import ContactListParams as ContactListParams +from .user_resolve_params import UserResolveParams as UserResolveParams +from .auth_whoami_response import AuthWhoamiResponse as AuthWhoamiResponse +from .user_search_response import UserSearchResponse as UserSearchResponse +from .contact_list_response import ContactListResponse as ContactListResponse +from .room_create_dm_params import RoomCreateDmParams as RoomCreateDmParams +from .user_resolve_response import UserResolveResponse as UserResolveResponse +from .auth_start_login_params import AuthStartLoginParams as AuthStartLoginParams +from .room_create_dm_response import RoomCreateDmResponse as RoomCreateDmResponse +from .auth_list_flows_response import AuthListFlowsResponse as AuthListFlowsResponse +from .room_create_group_params import RoomCreateGroupParams as RoomCreateGroupParams +from .auth_list_logins_response import AuthListLoginsResponse as AuthListLoginsResponse +from .auth_start_login_response import AuthStartLoginResponse as AuthStartLoginResponse +from .auth_submit_cookies_params import AuthSubmitCookiesParams as AuthSubmitCookiesParams +from .room_create_group_response import RoomCreateGroupResponse as RoomCreateGroupResponse +from .auth_wait_for_step_response import AuthWaitForStepResponse as AuthWaitForStepResponse +from .auth_submit_cookies_response import AuthSubmitCookiesResponse as AuthSubmitCookiesResponse +from .capability_retrieve_response import CapabilityRetrieveResponse as CapabilityRetrieveResponse +from .auth_submit_user_input_params import AuthSubmitUserInputParams as AuthSubmitUserInputParams +from .auth_submit_user_input_response import AuthSubmitUserInputResponse as AuthSubmitUserInputResponse diff --git a/src/beeper_desktop_api/types/matrix/bridges/auth_list_flows_response.py b/src/beeper_desktop_api/types/matrix/bridges/auth_list_flows_response.py new file mode 100644 index 0000000..05de99c --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/bridges/auth_list_flows_response.py @@ -0,0 +1,27 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from ...._models import BaseModel + +__all__ = ["AuthListFlowsResponse", "Flow"] + + +class Flow(BaseModel): + """An individual login flow which can be used to sign into the remote network.""" + + id: str + """ + An internal ID that is passed to the /login/start call to start a login with + this flow. + """ + + description: str + """A human-readable description of the login flow.""" + + name: str + """A human-readable name for the login flow.""" + + +class AuthListFlowsResponse(BaseModel): + flows: Optional[List[Flow]] = None diff --git a/src/beeper_desktop_api/types/matrix/bridges/auth_list_logins_response.py b/src/beeper_desktop_api/types/matrix/bridges/auth_list_logins_response.py new file mode 100644 index 0000000..a0e9d3a --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/bridges/auth_list_logins_response.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from ...._models import BaseModel + +__all__ = ["AuthListLoginsResponse"] + + +class AuthListLoginsResponse(BaseModel): + login_ids: Optional[List[str]] = None diff --git a/src/beeper_desktop_api/types/matrix/bridges/auth_start_login_params.py b/src/beeper_desktop_api/types/matrix/bridges/auth_start_login_params.py new file mode 100644 index 0000000..83368eb --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/bridges/auth_start_login_params.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from ...._utils import PropertyInfo + +__all__ = ["AuthStartLoginParams"] + + +class AuthStartLoginParams(TypedDict, total=False): + bridge_id: Required[Annotated[str, PropertyInfo(alias="bridgeID")]] + + login_id: str + """An existing login ID to re-login as. + + If this is specified and the user logs into a different account, the provided ID + will be logged out. + """ diff --git a/src/beeper_desktop_api/types/matrix/bridges/auth_start_login_response.py b/src/beeper_desktop_api/types/matrix/bridges/auth_start_login_response.py new file mode 100644 index 0000000..a63c5d6 --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/bridges/auth_start_login_response.py @@ -0,0 +1,278 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Union, Optional +from typing_extensions import Literal, TypeAlias + +from ...._models import BaseModel + +__all__ = [ + "AuthStartLoginResponse", + "UnionMember0", + "UnionMember0DisplayAndWait", + "UnionMember1", + "UnionMember1UserInput", + "UnionMember1UserInputField", + "UnionMember1UserInputAttachment", + "UnionMember1UserInputAttachmentInfo", + "UnionMember2", + "UnionMember2Cookies", + "UnionMember2CookiesField", + "UnionMember3", + "UnionMember3Complete", +] + + +class UnionMember0DisplayAndWait(BaseModel): + """Parameters for the display and wait login step""" + + type: Literal["qr", "emoji", "code", "nothing"] + """The type of thing to display""" + + data: Optional[str] = None + """ + The thing to display (raw data for QR, unicode emoji for emoji, plain string for + code) + """ + + image_url: Optional[str] = None + """An image containing the thing to display. + + If present, this is recommended over using data directly. For emojis, the URL to + the canonical image representation of the emoji + """ + + +class UnionMember0(BaseModel): + """Display and wait login step""" + + display_and_wait: UnionMember0DisplayAndWait + """Parameters for the display and wait login step""" + + type: Literal["display_and_wait"] + + instructions: Optional[str] = None + """Human-readable instructions for completing this login step.""" + + login_id: Optional[str] = None + """An identifier for the current login process. + + Must be passed to execute more steps of the login. + """ + + step_id: Optional[str] = None + """An unique ID identifying this step. + + This can be used to implement special behavior in clients. + """ + + +class UnionMember1UserInputField(BaseModel): + """A field that the user can fill.""" + + id: str + """The internal ID of the field. + + This must be used as the key in the object when submitting the data back to the + bridge. + """ + + name: str + """The name of the field shown to the user.""" + + type: Literal["username", "phone_number", "email", "password", "2fa_code", "token", "url", "domain", "select"] + """The type of field.""" + + default_value: Optional[str] = None + """A default value that the client can pre-fill the field with.""" + + description: Optional[str] = None + """A more detailed description of the field shown to the user.""" + + options: Optional[List[str]] = None + """For fields of type select, the valid options.""" + + pattern: Optional[str] = None + """A regular expression that the field value must match.""" + + +class UnionMember1UserInputAttachmentInfo(BaseModel): + """Optional but recommended metadata for the attachment. + + Can generally be derived from the raw content if omitted. + """ + + h: Optional[float] = None + """The height of the media in pixels. Only applicable for images and videos.""" + + mimetype: Optional[str] = None + """The MIME type for the media content.""" + + size: Optional[float] = None + """The size of the media content in number of bytes. + + Strongly recommended to include. + """ + + w: Optional[float] = None + """The width of the media in pixels. Only applicable for images and videos.""" + + +class UnionMember1UserInputAttachment(BaseModel): + """A media attachment to show the user.""" + + content: str + """The raw file content for the attachment encoded in base64.""" + + filename: str + """The filename for the media attachment.""" + + type: Literal["m.image", "m.audio"] + """ + The type of media attachment, using the same media type identifiers as Matrix + attachments. Only some are supported. + """ + + info: Optional[UnionMember1UserInputAttachmentInfo] = None + """Optional but recommended metadata for the attachment. + + Can generally be derived from the raw content if omitted. + """ + + +class UnionMember1UserInput(BaseModel): + """Parameters for the user input login step""" + + fields: List[UnionMember1UserInputField] + """The list of fields that the user is requested to fill.""" + + attachments: Optional[List[UnionMember1UserInputAttachment]] = None + """A list of media attachments to show the user alongside the form fields.""" + + +class UnionMember1(BaseModel): + """User input login step""" + + type: Literal["user_input"] + + user_input: UnionMember1UserInput + """Parameters for the user input login step""" + + instructions: Optional[str] = None + """Human-readable instructions for completing this login step.""" + + login_id: Optional[str] = None + """An identifier for the current login process. + + Must be passed to execute more steps of the login. + """ + + step_id: Optional[str] = None + """An unique ID identifying this step. + + This can be used to implement special behavior in clients. + """ + + +class UnionMember2CookiesField(BaseModel): + """An individual cookie or other stored data item that must be extracted.""" + + name: str + """The name of the item to extract.""" + + type: Literal["cookie", "local_storage", "request_header", "request_body", "special"] + """The type of data to extract.""" + + cookie_domain: Optional[str] = None + """For the `cookie` type, the domain of the cookie.""" + + request_url_regex: Optional[str] = None + """ + For the `request_header` and `request_body` types, a regex that matches the URLs + from which the values can be extracted. + """ + + +class UnionMember2Cookies(BaseModel): + """Parameters for the cookie login step""" + + fields: List[UnionMember2CookiesField] + """The list of cookies or other stored data that must be extracted.""" + + url: str + """The URL to open when using a webview to extract cookies.""" + + extract_js: Optional[str] = None + """ + A JavaScript snippet that can extract some or all of the fields. The snippet + will evaluate to a promise that resolves when the relevant fields are found. + Fields that are not present in the promise result must be extracted another way. + """ + + user_agent: Optional[str] = None + """An optional user agent that the webview should use.""" + + wait_for_url_pattern: Optional[str] = None + """A regex pattern that the URL should match before the client closes the webview. + + The client may submit the login if the user closes the webview after all cookies + are collected even if this URL is not reached, but it should only automatically + close the webview after both cookies and the URL match. + """ + + +class UnionMember2(BaseModel): + """Cookie login step""" + + cookies: UnionMember2Cookies + """Parameters for the cookie login step""" + + type: Literal["cookies"] + + instructions: Optional[str] = None + """Human-readable instructions for completing this login step.""" + + login_id: Optional[str] = None + """An identifier for the current login process. + + Must be passed to execute more steps of the login. + """ + + step_id: Optional[str] = None + """An unique ID identifying this step. + + This can be used to implement special behavior in clients. + """ + + +class UnionMember3Complete(BaseModel): + """Information about the completed login""" + + user_login_id: Optional[str] = None + """The unique ID of a login. Defined by the network connector.""" + + +class UnionMember3(BaseModel): + """Login complete""" + + complete: UnionMember3Complete + """Information about the completed login""" + + type: Literal["complete"] + + instructions: Optional[str] = None + """Human-readable instructions for completing this login step.""" + + login_id: Optional[str] = None + """An identifier for the current login process. + + Must be passed to execute more steps of the login. + """ + + step_id: Optional[str] = None + """An unique ID identifying this step. + + This can be used to implement special behavior in clients. + """ + + +AuthStartLoginResponse: TypeAlias = Union[UnionMember0, UnionMember1, UnionMember2, UnionMember3] diff --git a/src/beeper_desktop_api/types/matrix/bridges/auth_submit_cookies_params.py b/src/beeper_desktop_api/types/matrix/bridges/auth_submit_cookies_params.py new file mode 100644 index 0000000..21a5979 --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/bridges/auth_submit_cookies_params.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict +from typing_extensions import Required, Annotated, TypedDict + +from ...._utils import PropertyInfo + +__all__ = ["AuthSubmitCookiesParams"] + + +class AuthSubmitCookiesParams(TypedDict, total=False): + bridge_id: Required[Annotated[str, PropertyInfo(alias="bridgeID")]] + + login_process_id: Required[Annotated[str, PropertyInfo(alias="loginProcessID")]] + + body: Required[Dict[str, str]] diff --git a/src/beeper_desktop_api/types/matrix/bridges/auth_submit_cookies_response.py b/src/beeper_desktop_api/types/matrix/bridges/auth_submit_cookies_response.py new file mode 100644 index 0000000..a4c0ce0 --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/bridges/auth_submit_cookies_response.py @@ -0,0 +1,278 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Union, Optional +from typing_extensions import Literal, TypeAlias + +from ...._models import BaseModel + +__all__ = [ + "AuthSubmitCookiesResponse", + "UnionMember0", + "UnionMember0DisplayAndWait", + "UnionMember1", + "UnionMember1UserInput", + "UnionMember1UserInputField", + "UnionMember1UserInputAttachment", + "UnionMember1UserInputAttachmentInfo", + "UnionMember2", + "UnionMember2Cookies", + "UnionMember2CookiesField", + "UnionMember3", + "UnionMember3Complete", +] + + +class UnionMember0DisplayAndWait(BaseModel): + """Parameters for the display and wait login step""" + + type: Literal["qr", "emoji", "code", "nothing"] + """The type of thing to display""" + + data: Optional[str] = None + """ + The thing to display (raw data for QR, unicode emoji for emoji, plain string for + code) + """ + + image_url: Optional[str] = None + """An image containing the thing to display. + + If present, this is recommended over using data directly. For emojis, the URL to + the canonical image representation of the emoji + """ + + +class UnionMember0(BaseModel): + """Display and wait login step""" + + display_and_wait: UnionMember0DisplayAndWait + """Parameters for the display and wait login step""" + + type: Literal["display_and_wait"] + + instructions: Optional[str] = None + """Human-readable instructions for completing this login step.""" + + login_id: Optional[str] = None + """An identifier for the current login process. + + Must be passed to execute more steps of the login. + """ + + step_id: Optional[str] = None + """An unique ID identifying this step. + + This can be used to implement special behavior in clients. + """ + + +class UnionMember1UserInputField(BaseModel): + """A field that the user can fill.""" + + id: str + """The internal ID of the field. + + This must be used as the key in the object when submitting the data back to the + bridge. + """ + + name: str + """The name of the field shown to the user.""" + + type: Literal["username", "phone_number", "email", "password", "2fa_code", "token", "url", "domain", "select"] + """The type of field.""" + + default_value: Optional[str] = None + """A default value that the client can pre-fill the field with.""" + + description: Optional[str] = None + """A more detailed description of the field shown to the user.""" + + options: Optional[List[str]] = None + """For fields of type select, the valid options.""" + + pattern: Optional[str] = None + """A regular expression that the field value must match.""" + + +class UnionMember1UserInputAttachmentInfo(BaseModel): + """Optional but recommended metadata for the attachment. + + Can generally be derived from the raw content if omitted. + """ + + h: Optional[float] = None + """The height of the media in pixels. Only applicable for images and videos.""" + + mimetype: Optional[str] = None + """The MIME type for the media content.""" + + size: Optional[float] = None + """The size of the media content in number of bytes. + + Strongly recommended to include. + """ + + w: Optional[float] = None + """The width of the media in pixels. Only applicable for images and videos.""" + + +class UnionMember1UserInputAttachment(BaseModel): + """A media attachment to show the user.""" + + content: str + """The raw file content for the attachment encoded in base64.""" + + filename: str + """The filename for the media attachment.""" + + type: Literal["m.image", "m.audio"] + """ + The type of media attachment, using the same media type identifiers as Matrix + attachments. Only some are supported. + """ + + info: Optional[UnionMember1UserInputAttachmentInfo] = None + """Optional but recommended metadata for the attachment. + + Can generally be derived from the raw content if omitted. + """ + + +class UnionMember1UserInput(BaseModel): + """Parameters for the user input login step""" + + fields: List[UnionMember1UserInputField] + """The list of fields that the user is requested to fill.""" + + attachments: Optional[List[UnionMember1UserInputAttachment]] = None + """A list of media attachments to show the user alongside the form fields.""" + + +class UnionMember1(BaseModel): + """User input login step""" + + type: Literal["user_input"] + + user_input: UnionMember1UserInput + """Parameters for the user input login step""" + + instructions: Optional[str] = None + """Human-readable instructions for completing this login step.""" + + login_id: Optional[str] = None + """An identifier for the current login process. + + Must be passed to execute more steps of the login. + """ + + step_id: Optional[str] = None + """An unique ID identifying this step. + + This can be used to implement special behavior in clients. + """ + + +class UnionMember2CookiesField(BaseModel): + """An individual cookie or other stored data item that must be extracted.""" + + name: str + """The name of the item to extract.""" + + type: Literal["cookie", "local_storage", "request_header", "request_body", "special"] + """The type of data to extract.""" + + cookie_domain: Optional[str] = None + """For the `cookie` type, the domain of the cookie.""" + + request_url_regex: Optional[str] = None + """ + For the `request_header` and `request_body` types, a regex that matches the URLs + from which the values can be extracted. + """ + + +class UnionMember2Cookies(BaseModel): + """Parameters for the cookie login step""" + + fields: List[UnionMember2CookiesField] + """The list of cookies or other stored data that must be extracted.""" + + url: str + """The URL to open when using a webview to extract cookies.""" + + extract_js: Optional[str] = None + """ + A JavaScript snippet that can extract some or all of the fields. The snippet + will evaluate to a promise that resolves when the relevant fields are found. + Fields that are not present in the promise result must be extracted another way. + """ + + user_agent: Optional[str] = None + """An optional user agent that the webview should use.""" + + wait_for_url_pattern: Optional[str] = None + """A regex pattern that the URL should match before the client closes the webview. + + The client may submit the login if the user closes the webview after all cookies + are collected even if this URL is not reached, but it should only automatically + close the webview after both cookies and the URL match. + """ + + +class UnionMember2(BaseModel): + """Cookie login step""" + + cookies: UnionMember2Cookies + """Parameters for the cookie login step""" + + type: Literal["cookies"] + + instructions: Optional[str] = None + """Human-readable instructions for completing this login step.""" + + login_id: Optional[str] = None + """An identifier for the current login process. + + Must be passed to execute more steps of the login. + """ + + step_id: Optional[str] = None + """An unique ID identifying this step. + + This can be used to implement special behavior in clients. + """ + + +class UnionMember3Complete(BaseModel): + """Information about the completed login""" + + user_login_id: Optional[str] = None + """The unique ID of a login. Defined by the network connector.""" + + +class UnionMember3(BaseModel): + """Login complete""" + + complete: UnionMember3Complete + """Information about the completed login""" + + type: Literal["complete"] + + instructions: Optional[str] = None + """Human-readable instructions for completing this login step.""" + + login_id: Optional[str] = None + """An identifier for the current login process. + + Must be passed to execute more steps of the login. + """ + + step_id: Optional[str] = None + """An unique ID identifying this step. + + This can be used to implement special behavior in clients. + """ + + +AuthSubmitCookiesResponse: TypeAlias = Union[UnionMember0, UnionMember1, UnionMember2, UnionMember3] diff --git a/src/beeper_desktop_api/types/matrix/bridges/auth_submit_user_input_params.py b/src/beeper_desktop_api/types/matrix/bridges/auth_submit_user_input_params.py new file mode 100644 index 0000000..edbb7db --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/bridges/auth_submit_user_input_params.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict +from typing_extensions import Required, Annotated, TypedDict + +from ...._utils import PropertyInfo + +__all__ = ["AuthSubmitUserInputParams"] + + +class AuthSubmitUserInputParams(TypedDict, total=False): + bridge_id: Required[Annotated[str, PropertyInfo(alias="bridgeID")]] + + login_process_id: Required[Annotated[str, PropertyInfo(alias="loginProcessID")]] + + body: Required[Dict[str, str]] diff --git a/src/beeper_desktop_api/types/matrix/bridges/auth_submit_user_input_response.py b/src/beeper_desktop_api/types/matrix/bridges/auth_submit_user_input_response.py new file mode 100644 index 0000000..0f2808d --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/bridges/auth_submit_user_input_response.py @@ -0,0 +1,278 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Union, Optional +from typing_extensions import Literal, TypeAlias + +from ...._models import BaseModel + +__all__ = [ + "AuthSubmitUserInputResponse", + "UnionMember0", + "UnionMember0DisplayAndWait", + "UnionMember1", + "UnionMember1UserInput", + "UnionMember1UserInputField", + "UnionMember1UserInputAttachment", + "UnionMember1UserInputAttachmentInfo", + "UnionMember2", + "UnionMember2Cookies", + "UnionMember2CookiesField", + "UnionMember3", + "UnionMember3Complete", +] + + +class UnionMember0DisplayAndWait(BaseModel): + """Parameters for the display and wait login step""" + + type: Literal["qr", "emoji", "code", "nothing"] + """The type of thing to display""" + + data: Optional[str] = None + """ + The thing to display (raw data for QR, unicode emoji for emoji, plain string for + code) + """ + + image_url: Optional[str] = None + """An image containing the thing to display. + + If present, this is recommended over using data directly. For emojis, the URL to + the canonical image representation of the emoji + """ + + +class UnionMember0(BaseModel): + """Display and wait login step""" + + display_and_wait: UnionMember0DisplayAndWait + """Parameters for the display and wait login step""" + + type: Literal["display_and_wait"] + + instructions: Optional[str] = None + """Human-readable instructions for completing this login step.""" + + login_id: Optional[str] = None + """An identifier for the current login process. + + Must be passed to execute more steps of the login. + """ + + step_id: Optional[str] = None + """An unique ID identifying this step. + + This can be used to implement special behavior in clients. + """ + + +class UnionMember1UserInputField(BaseModel): + """A field that the user can fill.""" + + id: str + """The internal ID of the field. + + This must be used as the key in the object when submitting the data back to the + bridge. + """ + + name: str + """The name of the field shown to the user.""" + + type: Literal["username", "phone_number", "email", "password", "2fa_code", "token", "url", "domain", "select"] + """The type of field.""" + + default_value: Optional[str] = None + """A default value that the client can pre-fill the field with.""" + + description: Optional[str] = None + """A more detailed description of the field shown to the user.""" + + options: Optional[List[str]] = None + """For fields of type select, the valid options.""" + + pattern: Optional[str] = None + """A regular expression that the field value must match.""" + + +class UnionMember1UserInputAttachmentInfo(BaseModel): + """Optional but recommended metadata for the attachment. + + Can generally be derived from the raw content if omitted. + """ + + h: Optional[float] = None + """The height of the media in pixels. Only applicable for images and videos.""" + + mimetype: Optional[str] = None + """The MIME type for the media content.""" + + size: Optional[float] = None + """The size of the media content in number of bytes. + + Strongly recommended to include. + """ + + w: Optional[float] = None + """The width of the media in pixels. Only applicable for images and videos.""" + + +class UnionMember1UserInputAttachment(BaseModel): + """A media attachment to show the user.""" + + content: str + """The raw file content for the attachment encoded in base64.""" + + filename: str + """The filename for the media attachment.""" + + type: Literal["m.image", "m.audio"] + """ + The type of media attachment, using the same media type identifiers as Matrix + attachments. Only some are supported. + """ + + info: Optional[UnionMember1UserInputAttachmentInfo] = None + """Optional but recommended metadata for the attachment. + + Can generally be derived from the raw content if omitted. + """ + + +class UnionMember1UserInput(BaseModel): + """Parameters for the user input login step""" + + fields: List[UnionMember1UserInputField] + """The list of fields that the user is requested to fill.""" + + attachments: Optional[List[UnionMember1UserInputAttachment]] = None + """A list of media attachments to show the user alongside the form fields.""" + + +class UnionMember1(BaseModel): + """User input login step""" + + type: Literal["user_input"] + + user_input: UnionMember1UserInput + """Parameters for the user input login step""" + + instructions: Optional[str] = None + """Human-readable instructions for completing this login step.""" + + login_id: Optional[str] = None + """An identifier for the current login process. + + Must be passed to execute more steps of the login. + """ + + step_id: Optional[str] = None + """An unique ID identifying this step. + + This can be used to implement special behavior in clients. + """ + + +class UnionMember2CookiesField(BaseModel): + """An individual cookie or other stored data item that must be extracted.""" + + name: str + """The name of the item to extract.""" + + type: Literal["cookie", "local_storage", "request_header", "request_body", "special"] + """The type of data to extract.""" + + cookie_domain: Optional[str] = None + """For the `cookie` type, the domain of the cookie.""" + + request_url_regex: Optional[str] = None + """ + For the `request_header` and `request_body` types, a regex that matches the URLs + from which the values can be extracted. + """ + + +class UnionMember2Cookies(BaseModel): + """Parameters for the cookie login step""" + + fields: List[UnionMember2CookiesField] + """The list of cookies or other stored data that must be extracted.""" + + url: str + """The URL to open when using a webview to extract cookies.""" + + extract_js: Optional[str] = None + """ + A JavaScript snippet that can extract some or all of the fields. The snippet + will evaluate to a promise that resolves when the relevant fields are found. + Fields that are not present in the promise result must be extracted another way. + """ + + user_agent: Optional[str] = None + """An optional user agent that the webview should use.""" + + wait_for_url_pattern: Optional[str] = None + """A regex pattern that the URL should match before the client closes the webview. + + The client may submit the login if the user closes the webview after all cookies + are collected even if this URL is not reached, but it should only automatically + close the webview after both cookies and the URL match. + """ + + +class UnionMember2(BaseModel): + """Cookie login step""" + + cookies: UnionMember2Cookies + """Parameters for the cookie login step""" + + type: Literal["cookies"] + + instructions: Optional[str] = None + """Human-readable instructions for completing this login step.""" + + login_id: Optional[str] = None + """An identifier for the current login process. + + Must be passed to execute more steps of the login. + """ + + step_id: Optional[str] = None + """An unique ID identifying this step. + + This can be used to implement special behavior in clients. + """ + + +class UnionMember3Complete(BaseModel): + """Information about the completed login""" + + user_login_id: Optional[str] = None + """The unique ID of a login. Defined by the network connector.""" + + +class UnionMember3(BaseModel): + """Login complete""" + + complete: UnionMember3Complete + """Information about the completed login""" + + type: Literal["complete"] + + instructions: Optional[str] = None + """Human-readable instructions for completing this login step.""" + + login_id: Optional[str] = None + """An identifier for the current login process. + + Must be passed to execute more steps of the login. + """ + + step_id: Optional[str] = None + """An unique ID identifying this step. + + This can be used to implement special behavior in clients. + """ + + +AuthSubmitUserInputResponse: TypeAlias = Union[UnionMember0, UnionMember1, UnionMember2, UnionMember3] diff --git a/src/beeper_desktop_api/types/matrix/bridges/auth_wait_for_step_response.py b/src/beeper_desktop_api/types/matrix/bridges/auth_wait_for_step_response.py new file mode 100644 index 0000000..bd2fb65 --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/bridges/auth_wait_for_step_response.py @@ -0,0 +1,278 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Union, Optional +from typing_extensions import Literal, TypeAlias + +from ...._models import BaseModel + +__all__ = [ + "AuthWaitForStepResponse", + "UnionMember0", + "UnionMember0DisplayAndWait", + "UnionMember1", + "UnionMember1UserInput", + "UnionMember1UserInputField", + "UnionMember1UserInputAttachment", + "UnionMember1UserInputAttachmentInfo", + "UnionMember2", + "UnionMember2Cookies", + "UnionMember2CookiesField", + "UnionMember3", + "UnionMember3Complete", +] + + +class UnionMember0DisplayAndWait(BaseModel): + """Parameters for the display and wait login step""" + + type: Literal["qr", "emoji", "code", "nothing"] + """The type of thing to display""" + + data: Optional[str] = None + """ + The thing to display (raw data for QR, unicode emoji for emoji, plain string for + code) + """ + + image_url: Optional[str] = None + """An image containing the thing to display. + + If present, this is recommended over using data directly. For emojis, the URL to + the canonical image representation of the emoji + """ + + +class UnionMember0(BaseModel): + """Display and wait login step""" + + display_and_wait: UnionMember0DisplayAndWait + """Parameters for the display and wait login step""" + + type: Literal["display_and_wait"] + + instructions: Optional[str] = None + """Human-readable instructions for completing this login step.""" + + login_id: Optional[str] = None + """An identifier for the current login process. + + Must be passed to execute more steps of the login. + """ + + step_id: Optional[str] = None + """An unique ID identifying this step. + + This can be used to implement special behavior in clients. + """ + + +class UnionMember1UserInputField(BaseModel): + """A field that the user can fill.""" + + id: str + """The internal ID of the field. + + This must be used as the key in the object when submitting the data back to the + bridge. + """ + + name: str + """The name of the field shown to the user.""" + + type: Literal["username", "phone_number", "email", "password", "2fa_code", "token", "url", "domain", "select"] + """The type of field.""" + + default_value: Optional[str] = None + """A default value that the client can pre-fill the field with.""" + + description: Optional[str] = None + """A more detailed description of the field shown to the user.""" + + options: Optional[List[str]] = None + """For fields of type select, the valid options.""" + + pattern: Optional[str] = None + """A regular expression that the field value must match.""" + + +class UnionMember1UserInputAttachmentInfo(BaseModel): + """Optional but recommended metadata for the attachment. + + Can generally be derived from the raw content if omitted. + """ + + h: Optional[float] = None + """The height of the media in pixels. Only applicable for images and videos.""" + + mimetype: Optional[str] = None + """The MIME type for the media content.""" + + size: Optional[float] = None + """The size of the media content in number of bytes. + + Strongly recommended to include. + """ + + w: Optional[float] = None + """The width of the media in pixels. Only applicable for images and videos.""" + + +class UnionMember1UserInputAttachment(BaseModel): + """A media attachment to show the user.""" + + content: str + """The raw file content for the attachment encoded in base64.""" + + filename: str + """The filename for the media attachment.""" + + type: Literal["m.image", "m.audio"] + """ + The type of media attachment, using the same media type identifiers as Matrix + attachments. Only some are supported. + """ + + info: Optional[UnionMember1UserInputAttachmentInfo] = None + """Optional but recommended metadata for the attachment. + + Can generally be derived from the raw content if omitted. + """ + + +class UnionMember1UserInput(BaseModel): + """Parameters for the user input login step""" + + fields: List[UnionMember1UserInputField] + """The list of fields that the user is requested to fill.""" + + attachments: Optional[List[UnionMember1UserInputAttachment]] = None + """A list of media attachments to show the user alongside the form fields.""" + + +class UnionMember1(BaseModel): + """User input login step""" + + type: Literal["user_input"] + + user_input: UnionMember1UserInput + """Parameters for the user input login step""" + + instructions: Optional[str] = None + """Human-readable instructions for completing this login step.""" + + login_id: Optional[str] = None + """An identifier for the current login process. + + Must be passed to execute more steps of the login. + """ + + step_id: Optional[str] = None + """An unique ID identifying this step. + + This can be used to implement special behavior in clients. + """ + + +class UnionMember2CookiesField(BaseModel): + """An individual cookie or other stored data item that must be extracted.""" + + name: str + """The name of the item to extract.""" + + type: Literal["cookie", "local_storage", "request_header", "request_body", "special"] + """The type of data to extract.""" + + cookie_domain: Optional[str] = None + """For the `cookie` type, the domain of the cookie.""" + + request_url_regex: Optional[str] = None + """ + For the `request_header` and `request_body` types, a regex that matches the URLs + from which the values can be extracted. + """ + + +class UnionMember2Cookies(BaseModel): + """Parameters for the cookie login step""" + + fields: List[UnionMember2CookiesField] + """The list of cookies or other stored data that must be extracted.""" + + url: str + """The URL to open when using a webview to extract cookies.""" + + extract_js: Optional[str] = None + """ + A JavaScript snippet that can extract some or all of the fields. The snippet + will evaluate to a promise that resolves when the relevant fields are found. + Fields that are not present in the promise result must be extracted another way. + """ + + user_agent: Optional[str] = None + """An optional user agent that the webview should use.""" + + wait_for_url_pattern: Optional[str] = None + """A regex pattern that the URL should match before the client closes the webview. + + The client may submit the login if the user closes the webview after all cookies + are collected even if this URL is not reached, but it should only automatically + close the webview after both cookies and the URL match. + """ + + +class UnionMember2(BaseModel): + """Cookie login step""" + + cookies: UnionMember2Cookies + """Parameters for the cookie login step""" + + type: Literal["cookies"] + + instructions: Optional[str] = None + """Human-readable instructions for completing this login step.""" + + login_id: Optional[str] = None + """An identifier for the current login process. + + Must be passed to execute more steps of the login. + """ + + step_id: Optional[str] = None + """An unique ID identifying this step. + + This can be used to implement special behavior in clients. + """ + + +class UnionMember3Complete(BaseModel): + """Information about the completed login""" + + user_login_id: Optional[str] = None + """The unique ID of a login. Defined by the network connector.""" + + +class UnionMember3(BaseModel): + """Login complete""" + + complete: UnionMember3Complete + """Information about the completed login""" + + type: Literal["complete"] + + instructions: Optional[str] = None + """Human-readable instructions for completing this login step.""" + + login_id: Optional[str] = None + """An identifier for the current login process. + + Must be passed to execute more steps of the login. + """ + + step_id: Optional[str] = None + """An unique ID identifying this step. + + This can be used to implement special behavior in clients. + """ + + +AuthWaitForStepResponse: TypeAlias = Union[UnionMember0, UnionMember1, UnionMember2, UnionMember3] diff --git a/src/beeper_desktop_api/types/matrix/bridges/auth_whoami_response.py b/src/beeper_desktop_api/types/matrix/bridges/auth_whoami_response.py new file mode 100644 index 0000000..7bd7db7 --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/bridges/auth_whoami_response.py @@ -0,0 +1,128 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["AuthWhoamiResponse", "LoginFlow", "Login", "LoginProfile", "LoginState", "Network"] + + +class LoginFlow(BaseModel): + """An individual login flow which can be used to sign into the remote network.""" + + id: str + """ + An internal ID that is passed to the /login/start call to start a login with + this flow. + """ + + description: str + """A human-readable description of the login flow.""" + + name: str + """A human-readable name for the login flow.""" + + +class LoginProfile(BaseModel): + """The profile info of the logged-in user on the remote network.""" + + avatar: Optional[str] = None + """The user's avatar""" + + email: Optional[str] = None + """The user's email address""" + + name: Optional[str] = None + """The user's displayname""" + + phone: Optional[str] = None + """The user's phone number""" + + username: Optional[str] = None + """The user's username""" + + +class LoginState(BaseModel): + """The connection status of an individual login""" + + state_event: Literal["CONNECTING", "CONNECTED", "TRANSIENT_DISCONNECT", "BAD_CREDENTIALS", "UNKNOWN_ERROR"] + """The current state of this login.""" + + timestamp: float + """The time when the state was last updated.""" + + error: Optional[str] = None + """An error code defined by the network connector.""" + + info: Optional[object] = None + """Additional arbitrary info provided by the network connector.""" + + message: Optional[str] = None + """A human-readable error message defined by the network connector.""" + + reason: Optional[str] = None + """A reason code for non-error states that aren't exactly successes either.""" + + +class Login(BaseModel): + """The info of an individual login""" + + id: str + """The unique ID of a login. Defined by the network connector.""" + + name: str + """A human-readable name for the login. Defined by the network connector.""" + + profile: LoginProfile + """The profile info of the logged-in user on the remote network.""" + + state: LoginState + """The connection status of an individual login""" + + space_room: Optional[str] = None + """The personal filtering space room ID for this login.""" + + +class Network(BaseModel): + """Info about the network that the bridge is bridging to.""" + + beeper_bridge_type: str + """An identifier uniquely identifying the bridge software.""" + + displayname: str + """The displayname of the network.""" + + network_icon: str + """The icon of the network as a `mxc://` URI.""" + + network_id: str + """An identifier uniquely identifying the network.""" + + network_url: str + """The URL to the website of the network.""" + + +class AuthWhoamiResponse(BaseModel): + """Info about the bridge and user""" + + bridge_bot: str + """The Matrix user ID of the bridge bot.""" + + command_prefix: str + """The command prefix used by this bridge.""" + + homeserver: str + """The server name the bridge is running on.""" + + login_flows: List[LoginFlow] + """The login flows that the bridge supports.""" + + logins: List[Login] + """The logins of the user who made the /whoami call""" + + network: Network + """Info about the network that the bridge is bridging to.""" + + management_room: Optional[str] = None + """The Matrix management room ID of the user who made the /whoami call.""" diff --git a/src/beeper_desktop_api/types/matrix/bridges/capability_retrieve_response.py b/src/beeper_desktop_api/types/matrix/bridges/capability_retrieve_response.py new file mode 100644 index 0000000..18c6716 --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/bridges/capability_retrieve_response.py @@ -0,0 +1,8 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict +from typing_extensions import TypeAlias + +__all__ = ["CapabilityRetrieveResponse"] + +CapabilityRetrieveResponse: TypeAlias = Dict[str, object] diff --git a/src/beeper_desktop_api/types/matrix/bridges/contact_list_params.py b/src/beeper_desktop_api/types/matrix/bridges/contact_list_params.py new file mode 100644 index 0000000..73465db --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/bridges/contact_list_params.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import TypedDict + +__all__ = ["ContactListParams"] + + +class ContactListParams(TypedDict, total=False): + login_id: str + """An optional explicit login ID to do the action through.""" diff --git a/src/beeper_desktop_api/types/matrix/bridges/contact_list_response.py b/src/beeper_desktop_api/types/matrix/bridges/contact_list_response.py new file mode 100644 index 0000000..c0b51dc --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/bridges/contact_list_response.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from ...._models import BaseModel + +__all__ = ["ContactListResponse", "Contact"] + + +class Contact(BaseModel): + """A successfully resolved identifier.""" + + id: str + """The internal user ID of the resolved user.""" + + avatar_url: Optional[str] = None + """The avatar of the user on the remote network.""" + + dm_room_mxid: Optional[str] = None + """The Matrix room ID of the direct chat with the user.""" + + identifiers: Optional[List[str]] = None + """A list of identifiers for the user on the remote network.""" + + mxid: Optional[str] = None + """The Matrix user ID of the ghost representing the user.""" + + name: Optional[str] = None + """The name of the user on the remote network.""" + + +class ContactListResponse(BaseModel): + contacts: Optional[List[Contact]] = None diff --git a/src/beeper_desktop_api/types/matrix/bridges/room_create_dm_params.py b/src/beeper_desktop_api/types/matrix/bridges/room_create_dm_params.py new file mode 100644 index 0000000..5535a29 --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/bridges/room_create_dm_params.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from ...._utils import PropertyInfo + +__all__ = ["RoomCreateDmParams"] + + +class RoomCreateDmParams(TypedDict, total=False): + bridge_id: Required[Annotated[str, PropertyInfo(alias="bridgeID")]] + + login_id: str + """An optional explicit login ID to do the action through.""" diff --git a/src/beeper_desktop_api/types/matrix/bridges/room_create_dm_response.py b/src/beeper_desktop_api/types/matrix/bridges/room_create_dm_response.py new file mode 100644 index 0000000..f15debc --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/bridges/room_create_dm_response.py @@ -0,0 +1,29 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from ...._models import BaseModel + +__all__ = ["RoomCreateDmResponse"] + + +class RoomCreateDmResponse(BaseModel): + """A successfully resolved identifier.""" + + id: str + """The internal user ID of the resolved user.""" + + avatar_url: Optional[str] = None + """The avatar of the user on the remote network.""" + + dm_room_mxid: Optional[str] = None + """The Matrix room ID of the direct chat with the user.""" + + identifiers: Optional[List[str]] = None + """A list of identifiers for the user on the remote network.""" + + mxid: Optional[str] = None + """The Matrix user ID of the ghost representing the user.""" + + name: Optional[str] = None + """The name of the user on the remote network.""" diff --git a/src/beeper_desktop_api/types/matrix/bridges/room_create_group_params.py b/src/beeper_desktop_api/types/matrix/bridges/room_create_group_params.py new file mode 100644 index 0000000..de9c10d --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/bridges/room_create_group_params.py @@ -0,0 +1,72 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from ...._types import SequenceNotStr +from ...._utils import PropertyInfo + +__all__ = ["RoomCreateGroupParams", "Avatar", "Disappear", "Name", "Topic"] + + +class RoomCreateGroupParams(TypedDict, total=False): + bridge_id: Required[Annotated[str, PropertyInfo(alias="bridgeID")]] + + login_id: str + """An optional explicit login ID to do the action through.""" + + avatar: Avatar + """The `m.room.avatar` event content for the room.""" + + disappear: Disappear + """The `com.beeper.disappearing_timer` event content for the room.""" + + name: Name + """The `m.room.name` event content for the room.""" + + parent: object + + participants: SequenceNotStr[str] + """The users to add to the group initially.""" + + room_id: str + """ + An existing Matrix room ID to bridge to. The other parameters must be already in + sync with the room state when using this parameter. + """ + + topic: Topic + """The `m.room.topic` event content for the room.""" + + type: str + """The type of group to create.""" + + username: str + """The public username for the created group.""" + + +class Avatar(TypedDict, total=False): + """The `m.room.avatar` event content for the room.""" + + url: str + + +class Disappear(TypedDict, total=False): + """The `com.beeper.disappearing_timer` event content for the room.""" + + timer: float + + type: str + + +class Name(TypedDict, total=False): + """The `m.room.name` event content for the room.""" + + name: str + + +class Topic(TypedDict, total=False): + """The `m.room.topic` event content for the room.""" + + topic: str diff --git a/src/beeper_desktop_api/types/matrix/bridges/room_create_group_response.py b/src/beeper_desktop_api/types/matrix/bridges/room_create_group_response.py new file mode 100644 index 0000000..824275b --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/bridges/room_create_group_response.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ...._models import BaseModel + +__all__ = ["RoomCreateGroupResponse"] + + +class RoomCreateGroupResponse(BaseModel): + """A successfully created group chat.""" + + id: str + """The internal chat ID of the created group.""" + + mxid: str + """The Matrix room ID of the portal.""" diff --git a/src/beeper_desktop_api/types/matrix/bridges/user_resolve_params.py b/src/beeper_desktop_api/types/matrix/bridges/user_resolve_params.py new file mode 100644 index 0000000..46d6b21 --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/bridges/user_resolve_params.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from ...._utils import PropertyInfo + +__all__ = ["UserResolveParams"] + + +class UserResolveParams(TypedDict, total=False): + bridge_id: Required[Annotated[str, PropertyInfo(alias="bridgeID")]] + + login_id: str + """An optional explicit login ID to do the action through.""" diff --git a/src/beeper_desktop_api/types/matrix/bridges/user_resolve_response.py b/src/beeper_desktop_api/types/matrix/bridges/user_resolve_response.py new file mode 100644 index 0000000..22b2517 --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/bridges/user_resolve_response.py @@ -0,0 +1,29 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from ...._models import BaseModel + +__all__ = ["UserResolveResponse"] + + +class UserResolveResponse(BaseModel): + """A successfully resolved identifier.""" + + id: str + """The internal user ID of the resolved user.""" + + avatar_url: Optional[str] = None + """The avatar of the user on the remote network.""" + + dm_room_mxid: Optional[str] = None + """The Matrix room ID of the direct chat with the user.""" + + identifiers: Optional[List[str]] = None + """A list of identifiers for the user on the remote network.""" + + mxid: Optional[str] = None + """The Matrix user ID of the ghost representing the user.""" + + name: Optional[str] = None + """The name of the user on the remote network.""" diff --git a/src/beeper_desktop_api/types/matrix/bridges/user_search_params.py b/src/beeper_desktop_api/types/matrix/bridges/user_search_params.py new file mode 100644 index 0000000..45190a8 --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/bridges/user_search_params.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import TypedDict + +__all__ = ["UserSearchParams"] + + +class UserSearchParams(TypedDict, total=False): + login_id: str + """An optional explicit login ID to do the action through.""" + + query: str + """The search query to send to the remote network""" diff --git a/src/beeper_desktop_api/types/matrix/bridges/user_search_response.py b/src/beeper_desktop_api/types/matrix/bridges/user_search_response.py new file mode 100644 index 0000000..c001e5c --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/bridges/user_search_response.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from ...._models import BaseModel + +__all__ = ["UserSearchResponse", "Result"] + + +class Result(BaseModel): + """A successfully resolved identifier.""" + + id: str + """The internal user ID of the resolved user.""" + + avatar_url: Optional[str] = None + """The avatar of the user on the remote network.""" + + dm_room_mxid: Optional[str] = None + """The Matrix room ID of the direct chat with the user.""" + + identifiers: Optional[List[str]] = None + """A list of identifiers for the user on the remote network.""" + + mxid: Optional[str] = None + """The Matrix user ID of the ghost representing the user.""" + + name: Optional[str] = None + """The name of the user on the remote network.""" + + +class UserSearchResponse(BaseModel): + results: Optional[List[Result]] = None diff --git a/src/beeper_desktop_api/types/matrix/room_create_params.py b/src/beeper_desktop_api/types/matrix/room_create_params.py new file mode 100644 index 0000000..073228e --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/room_create_params.py @@ -0,0 +1,157 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable +from typing_extensions import Literal, Required, TypedDict + +from ..._types import SequenceNotStr + +__all__ = ["RoomCreateParams", "InitialState", "Invite3pid"] + + +class RoomCreateParams(TypedDict, total=False): + creation_content: object + """ + Extra keys, such as `m.federate`, to be added to the content of the + [`m.room.create`](https://spec.matrix.org/v1.18/client-server-api/#mroomcreate) + event. + + The server will overwrite the following keys: `creator`, `room_version`. Future + versions of the specification may allow the server to overwrite other keys. + + When using the `trusted_private_chat` preset, the server SHOULD combine + `additional_creators` specified here and the `invite` array into the eventual + `m.room.create` event's `additional_creators`, deduplicating between the two + parameters. + """ + + initial_state: Iterable[InitialState] + """A list of state events to set in the new room. + + This allows the user to override the default state events set in the new room. + The expected format of the state events are an object with type, state_key and + content keys set. + + Takes precedence over events set by `preset`, but gets overridden by `name` and + `topic` keys. + """ + + invite: SequenceNotStr[str] + """A list of user IDs to invite to the room. + + This will tell the server to invite everyone in the list to the newly created + room. + """ + + invite_3pid: Iterable[Invite3pid] + """A list of objects representing third-party IDs to invite into the room.""" + + is_direct: bool + """ + This flag makes the server set the `is_direct` flag on the `m.room.member` + events sent to the users in `invite` and `invite_3pid`. See + [Direct Messaging](https://spec.matrix.org/v1.18/client-server-api/#direct-messaging) + for more information. + """ + + name: str + """ + If this is included, an + [`m.room.name`](https://spec.matrix.org/v1.18/client-server-api/#mroomname) + event will be sent into the room to indicate the name for the room. This + overwrites any + [`m.room.name`](https://spec.matrix.org/v1.18/client-server-api/#mroomname) + event in `initial_state`. + """ + + power_level_content_override: object + """The power level content to override in the default power level event. + + This object is applied on top of the generated + [`m.room.power_levels`](https://spec.matrix.org/v1.18/client-server-api/#mroompower_levels) + event content prior to it being sent to the room. Defaults to overriding + nothing. + """ + + preset: Literal["private_chat", "public_chat", "trusted_private_chat"] + """ + Convenience parameter for setting various default state events based on a + preset. + + If unspecified, the server should use the `visibility` to determine which preset + to use. A visibility of `public` equates to a preset of `public_chat` and + `private` visibility equates to a preset of `private_chat`. + """ + + room_alias_name: str + """The desired room alias **local part**. + + If this is included, a room alias will be created and mapped to the newly + created room. The alias will belong on the _same_ homeserver which created the + room. For example, if this was set to "foo" and sent to the homeserver + "example.com" the complete room alias would be `#foo:example.com`. + + The complete room alias will become the canonical alias for the room and an + `m.room.canonical_alias` event will be sent into the room. + """ + + room_version: str + """The room version to set for the room. + + If not provided, the homeserver is to use its configured default. If provided, + the homeserver will return a 400 error with the errcode + `M_UNSUPPORTED_ROOM_VERSION` if it does not support the room version. + """ + + topic: str + """ + If this is included, an + [`m.room.topic`](https://spec.matrix.org/v1.18/client-server-api/#mroomtopic) + event with a `text/plain` mimetype will be sent into the room to indicate the + topic for the room. This overwrites any + [`m.room.topic`](https://spec.matrix.org/v1.18/client-server-api/#mroomtopic) + event in `initial_state`. + """ + + visibility: Literal["public", "private"] + """ + The room's visibility in the server's + [published room directory](https://spec.matrix.org/v1.18/client-server-api#published-room-directory). + Defaults to `private`. + """ + + +class InitialState(TypedDict, total=False): + content: Required[object] + """The content of the event.""" + + type: Required[str] + """The type of event to send.""" + + state_key: str + """The state_key of the state event. Defaults to an empty string.""" + + +class Invite3pid(TypedDict, total=False): + address: Required[str] + """The invitee's third-party identifier.""" + + id_access_token: Required[str] + """An access token previously registered with the identity server. + + Servers can treat this as optional to distinguish between r0.5-compatible + clients and this specification version. + """ + + id_server: Required[str] + """ + The hostname+port of the identity server which should be used for third-party + identifier lookups. + """ + + medium: Required[str] + """ + The kind of address being passed in the address field, for example `email` (see + [the list of recognised values](https://spec.matrix.org/v1.18/appendices/#3pid-types)). + """ diff --git a/src/beeper_desktop_api/types/matrix/room_create_response.py b/src/beeper_desktop_api/types/matrix/room_create_response.py new file mode 100644 index 0000000..e8559bf --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/room_create_response.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ..._models import BaseModel + +__all__ = ["RoomCreateResponse"] + + +class RoomCreateResponse(BaseModel): + """Information about the newly created room.""" + + room_id: str + """The created room's ID.""" diff --git a/src/beeper_desktop_api/types/matrix/room_join_params.py b/src/beeper_desktop_api/types/matrix/room_join_params.py new file mode 100644 index 0000000..2bbc93b --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/room_join_params.py @@ -0,0 +1,49 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict +from typing_extensions import Required, TypedDict + +from ..._types import SequenceNotStr + +__all__ = ["RoomJoinParams", "ThirdPartySigned"] + + +class RoomJoinParams(TypedDict, total=False): + via: SequenceNotStr[str] + """The servers to attempt to join the room through. + + One of the servers must be participating in the room. + """ + + reason: str + """ + Optional reason to be included as the `reason` on the subsequent membership + event. + """ + + third_party_signed: ThirdPartySigned + """ + A signature of an `m.third_party_invite` token to prove that this user owns a + third-party identity which has been invited to the room. + """ + + +class ThirdPartySigned(TypedDict, total=False): + """ + A signature of an `m.third_party_invite` token to prove that this user + owns a third-party identity which has been invited to the room. + """ + + token: Required[str] + """The state key of the m.third_party_invite event.""" + + mxid: Required[str] + """The Matrix ID of the invitee.""" + + sender: Required[str] + """The Matrix ID of the user who issued the invite.""" + + signatures: Required[Dict[str, Dict[str, str]]] + """A signatures object containing a signature of the entire signed object.""" diff --git a/src/beeper_desktop_api/types/matrix/room_join_response.py b/src/beeper_desktop_api/types/matrix/room_join_response.py new file mode 100644 index 0000000..337f661 --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/room_join_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ..._models import BaseModel + +__all__ = ["RoomJoinResponse"] + + +class RoomJoinResponse(BaseModel): + room_id: str + """The joined room ID.""" diff --git a/src/beeper_desktop_api/types/matrix/room_leave_params.py b/src/beeper_desktop_api/types/matrix/room_leave_params.py new file mode 100644 index 0000000..1641101 --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/room_leave_params.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import TypedDict + +__all__ = ["RoomLeaveParams"] + + +class RoomLeaveParams(TypedDict, total=False): + reason: str + """ + Optional reason to be included as the `reason` on the subsequent membership + event. + """ diff --git a/src/beeper_desktop_api/types/matrix/rooms/__init__.py b/src/beeper_desktop_api/types/matrix/rooms/__init__.py new file mode 100644 index 0000000..39de1f8 --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/rooms/__init__.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .state_list_response import StateListResponse as StateListResponse +from .state_retrieve_params import StateRetrieveParams as StateRetrieveParams +from .event_retrieve_response import EventRetrieveResponse as EventRetrieveResponse +from .state_retrieve_response import StateRetrieveResponse as StateRetrieveResponse +from .account_data_update_params import AccountDataUpdateParams as AccountDataUpdateParams diff --git a/src/beeper_desktop_api/types/matrix/rooms/account_data_update_params.py b/src/beeper_desktop_api/types/matrix/rooms/account_data_update_params.py new file mode 100644 index 0000000..aa8463a --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/rooms/account_data_update_params.py @@ -0,0 +1,17 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from ...._utils import PropertyInfo + +__all__ = ["AccountDataUpdateParams"] + + +class AccountDataUpdateParams(TypedDict, total=False): + user_id: Required[Annotated[str, PropertyInfo(alias="userId")]] + + room_id: Required[Annotated[str, PropertyInfo(alias="roomId")]] + + body: Required[object] diff --git a/src/beeper_desktop_api/types/matrix/rooms/event_retrieve_response.py b/src/beeper_desktop_api/types/matrix/rooms/event_retrieve_response.py new file mode 100644 index 0000000..f39b2fe --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/rooms/event_retrieve_response.py @@ -0,0 +1,94 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from ...._models import BaseModel + +__all__ = ["EventRetrieveResponse", "Unsigned"] + + +class Unsigned(BaseModel): + age: Optional[int] = None + """The time in milliseconds that has elapsed since the event was sent. + + This field is generated by the local homeserver, and may be incorrect if the + local time on at least one of the two servers is out of sync, which can cause + the age to either be negative or greater than it actually is. + """ + + membership: Optional[str] = None + """The room membership of the user making the request, at the time of the event. + + This property is the value of the `membership` property of the requesting user's + [`m.room.member`](https://spec.matrix.org/v1.18/client-server-api#mroommember) + state at the point of the event, including any changes caused by the event. If + the user had yet to join the room at the time of the event (i.e, they have no + `m.room.member` state), this property is set to `leave`. + + Homeservers SHOULD populate this property wherever practical, but they MAY omit + it if necessary (for example, if calculating the value is expensive, servers + might choose to only implement it in encrypted rooms). The property is _not_ + normally populated in events pushed to application services via the application + service transaction API (where there is no clear definition of "requesting + user"). + """ + + prev_content: Optional[object] = None + """The previous `content` for this event. + + This field is generated by the local homeserver, and is only returned if the + event is a state event, and the client has permission to see the previous + content. + """ + + redacted_because: Optional[object] = None + + transaction_id: Optional[str] = None + """ + The client-supplied + [transaction ID](https://spec.matrix.org/v1.18/client-server-api/#transaction-identifiers), + for example, provided via + `PUT /_matrix/client/v3/rooms/{roomId}/send/{eventType}/{txnId}`, if the client + being given the event is the same one which sent it. + """ + + +class EventRetrieveResponse(BaseModel): + """ + The format used for events when they are returned from a homeserver to a client + via the Client-Server API, or sent to an Application Service via the Application Services API. + """ + + content: object + """The body of this event, as created by the client which sent it.""" + + event_id: str + """The globally unique identifier for this event.""" + + origin_server_ts: int + """ + Timestamp (in milliseconds since the unix epoch) on originating homeserver when + this event was sent. + """ + + room_id: str + """The ID of the room associated with this event.""" + + sender: str + """Contains the fully-qualified ID of the user who sent this event.""" + + type: str + """The type of the event.""" + + state_key: Optional[str] = None + """Present if, and only if, this event is a _state_ event. + + The key making this piece of state unique in the room. Note that it is often an + empty string. + + State keys starting with an `@` are reserved for referencing user IDs, such as + room members. With the exception of a few events, state events set with a given + user's ID as the state key MUST only be set by that user. + """ + + unsigned: Optional[Unsigned] = None diff --git a/src/beeper_desktop_api/types/matrix/rooms/state_list_response.py b/src/beeper_desktop_api/types/matrix/rooms/state_list_response.py new file mode 100644 index 0000000..1f879ef --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/rooms/state_list_response.py @@ -0,0 +1,98 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import TypeAlias + +from ...._models import BaseModel + +__all__ = ["StateListResponse", "StateListResponseItem", "StateListResponseItemUnsigned"] + + +class StateListResponseItemUnsigned(BaseModel): + age: Optional[int] = None + """The time in milliseconds that has elapsed since the event was sent. + + This field is generated by the local homeserver, and may be incorrect if the + local time on at least one of the two servers is out of sync, which can cause + the age to either be negative or greater than it actually is. + """ + + membership: Optional[str] = None + """The room membership of the user making the request, at the time of the event. + + This property is the value of the `membership` property of the requesting user's + [`m.room.member`](https://spec.matrix.org/v1.18/client-server-api#mroommember) + state at the point of the event, including any changes caused by the event. If + the user had yet to join the room at the time of the event (i.e, they have no + `m.room.member` state), this property is set to `leave`. + + Homeservers SHOULD populate this property wherever practical, but they MAY omit + it if necessary (for example, if calculating the value is expensive, servers + might choose to only implement it in encrypted rooms). The property is _not_ + normally populated in events pushed to application services via the application + service transaction API (where there is no clear definition of "requesting + user"). + """ + + prev_content: Optional[object] = None + """The previous `content` for this event. + + This field is generated by the local homeserver, and is only returned if the + event is a state event, and the client has permission to see the previous + content. + """ + + redacted_because: Optional[object] = None + + transaction_id: Optional[str] = None + """ + The client-supplied + [transaction ID](https://spec.matrix.org/v1.18/client-server-api/#transaction-identifiers), + for example, provided via + `PUT /_matrix/client/v3/rooms/{roomId}/send/{eventType}/{txnId}`, if the client + being given the event is the same one which sent it. + """ + + +class StateListResponseItem(BaseModel): + """ + The format used for events when they are returned from a homeserver to a client + via the Client-Server API, or sent to an Application Service via the Application Services API. + """ + + content: object + """The body of this event, as created by the client which sent it.""" + + event_id: str + """The globally unique identifier for this event.""" + + origin_server_ts: int + """ + Timestamp (in milliseconds since the unix epoch) on originating homeserver when + this event was sent. + """ + + room_id: str + """The ID of the room associated with this event.""" + + sender: str + """Contains the fully-qualified ID of the user who sent this event.""" + + type: str + """The type of the event.""" + + state_key: Optional[str] = None + """Present if, and only if, this event is a _state_ event. + + The key making this piece of state unique in the room. Note that it is often an + empty string. + + State keys starting with an `@` are reserved for referencing user IDs, such as + room members. With the exception of a few events, state events set with a given + user's ID as the state key MUST only be set by that user. + """ + + unsigned: Optional[StateListResponseItemUnsigned] = None + + +StateListResponse: TypeAlias = List[StateListResponseItem] diff --git a/src/beeper_desktop_api/types/matrix/rooms/state_retrieve_params.py b/src/beeper_desktop_api/types/matrix/rooms/state_retrieve_params.py new file mode 100644 index 0000000..c2a4d7d --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/rooms/state_retrieve_params.py @@ -0,0 +1,23 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ...._utils import PropertyInfo + +__all__ = ["StateRetrieveParams"] + + +class StateRetrieveParams(TypedDict, total=False): + room_id: Required[Annotated[str, PropertyInfo(alias="roomId")]] + + event_type: Required[Annotated[str, PropertyInfo(alias="eventType")]] + + format: Literal["content", "event"] + """The format to use for the returned data. + + `content` (the default) will return only the content of the state event. `event` + will return the entire event in the usual format suitable for clients, including + fields like event ID, sender and timestamp. + """ diff --git a/src/beeper_desktop_api/types/matrix/rooms/state_retrieve_response.py b/src/beeper_desktop_api/types/matrix/rooms/state_retrieve_response.py new file mode 100644 index 0000000..4f07375 --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/rooms/state_retrieve_response.py @@ -0,0 +1,8 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict +from typing_extensions import TypeAlias + +__all__ = ["StateRetrieveResponse"] + +StateRetrieveResponse: TypeAlias = Dict[str, object] diff --git a/src/beeper_desktop_api/types/matrix/user_retrieve_profile_response.py b/src/beeper_desktop_api/types/matrix/user_retrieve_profile_response.py new file mode 100644 index 0000000..9ad6009 --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/user_retrieve_profile_response.py @@ -0,0 +1,32 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import TYPE_CHECKING, Dict, Optional + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["UserRetrieveProfileResponse"] + + +class UserRetrieveProfileResponse(BaseModel): + avatar_url: Optional[str] = None + """The user's avatar URL if they have set one, otherwise not present.""" + + displayname: Optional[str] = None + """The user's display name if they have set one, otherwise not present.""" + + m_tz: Optional[str] = FieldInfo(alias="m.tz", default=None) + """The user's time zone.""" + + if TYPE_CHECKING: + # Some versions of Pydantic <2.8.0 have a bug and don’t allow assigning a + # value to this field, so for compatibility we avoid doing it at runtime. + __pydantic_extra__: Dict[str, object] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride] + + # Stub to indicate that arbitrary properties are accepted. + # To access properties that are not valid identifiers you can use `getattr`, e.g. + # `getattr(obj, '$type')` + def __getattr__(self, attr: str) -> object: ... + else: + __pydantic_extra__: Dict[str, object] diff --git a/src/beeper_desktop_api/types/matrix/users/__init__.py b/src/beeper_desktop_api/types/matrix/users/__init__.py new file mode 100644 index 0000000..65bf6e2 --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/users/__init__.py @@ -0,0 +1,5 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .account_data_update_params import AccountDataUpdateParams as AccountDataUpdateParams diff --git a/src/beeper_desktop_api/types/matrix/users/account_data_update_params.py b/src/beeper_desktop_api/types/matrix/users/account_data_update_params.py new file mode 100644 index 0000000..b1d58de --- /dev/null +++ b/src/beeper_desktop_api/types/matrix/users/account_data_update_params.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from ...._utils import PropertyInfo + +__all__ = ["AccountDataUpdateParams"] + + +class AccountDataUpdateParams(TypedDict, total=False): + user_id: Required[Annotated[str, PropertyInfo(alias="userId")]] + + body: Required[object] diff --git a/src/beeper_desktop_api/types/shared/__init__.py b/src/beeper_desktop_api/types/shared/__init__.py index cb669ed..63cd244 100644 --- a/src/beeper_desktop_api/types/shared/__init__.py +++ b/src/beeper_desktop_api/types/shared/__init__.py @@ -5,3 +5,4 @@ from .message import Message as Message from .reaction import Reaction as Reaction from .attachment import Attachment as Attachment +from .app_state_snapshot import AppStateSnapshot as AppStateSnapshot diff --git a/src/beeper_desktop_api/types/shared/app_state_snapshot.py b/src/beeper_desktop_api/types/shared/app_state_snapshot.py new file mode 100644 index 0000000..88fc131 --- /dev/null +++ b/src/beeper_desktop_api/types/shared/app_state_snapshot.py @@ -0,0 +1,154 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["AppStateSnapshot", "E2ee", "E2eeSecrets", "Matrix", "Verification", "VerificationError", "VerificationSas"] + + +class E2eeSecrets(BaseModel): + """Encrypted messaging keys available on this device.""" + + master_key: bool = FieldInfo(alias="masterKey") + """Whether the account identity key is available.""" + + megolm_backup_key: bool = FieldInfo(alias="megolmBackupKey") + """Whether the encrypted message backup key is available.""" + + recovery_code: bool = FieldInfo(alias="recoveryCode") + """Whether a recovery key is available.""" + + self_signing_key: bool = FieldInfo(alias="selfSigningKey") + """Whether the device trust key is available.""" + + user_signing_key: bool = FieldInfo(alias="userSigningKey") + """Whether the user trust key is available.""" + + +class E2ee(BaseModel): + """Encrypted messaging setup status.""" + + cross_signing: bool = FieldInfo(alias="crossSigning") + """Whether this account can verify trusted devices.""" + + first_sync_done: bool = FieldInfo(alias="firstSyncDone") + """Whether the first encrypted message sync is complete.""" + + has_backed_up_code: bool = FieldInfo(alias="hasBackedUpCode") + """Whether the user confirmed that they saved their recovery key.""" + + initialized: bool + """Whether encrypted messaging setup has started.""" + + key_backup: bool = FieldInfo(alias="keyBackup") + """Whether encrypted message backup is available.""" + + secrets: E2eeSecrets + """Encrypted messaging keys available on this device.""" + + secret_storage: bool = FieldInfo(alias="secretStorage") + """Whether secure key storage is available.""" + + verified: bool + """Whether this device is trusted for encrypted messages.""" + + recovery_code_generated_at: Optional[float] = FieldInfo(alias="recoveryCodeGeneratedAt", default=None) + """Unix timestamp for when the recovery key was created.""" + + +class Matrix(BaseModel): + """Signed-in account details. Omitted until sign-in is complete.""" + + device_id: str = FieldInfo(alias="deviceID") + """Current device ID.""" + + homeserver: str + """Beeper server URL for this account.""" + + user_id: str = FieldInfo(alias="userID") + """Signed-in Beeper user ID.""" + + +class VerificationError(BaseModel): + """Verification error details, if verification stopped.""" + + code: str + """Verification error code.""" + + reason: str + """User-facing verification error message.""" + + +class VerificationSas(BaseModel): + """Emoji or number comparison data for verification.""" + + decimals: str + """Number sequence to compare on both devices.""" + + emojis: str + """Emoji sequence to compare on both devices.""" + + +class Verification(BaseModel): + """Trusted-device verification progress.""" + + available_actions: List[ + Literal["create", "qr.scan", "accept", "cancel", "qr.confirmScanned", "sas.start", "sas.confirm"] + ] = FieldInfo(alias="availableActions") + """Verification actions that are valid for the current state.""" + + state: Literal["idle", "requested", "ready", "sas_ready", "qr_scanned", "done", "cancelled", "error"] + """Current trusted-device verification state.""" + + error: Optional[VerificationError] = None + """Verification error details, if verification stopped.""" + + from_: Optional[str] = FieldInfo(alias="from", default=None) + """User ID that started verification.""" + + from_device: Optional[str] = FieldInfo(alias="fromDevice", default=None) + """Device that started verification.""" + + other_device: Optional[str] = FieldInfo(alias="otherDevice", default=None) + """Other device participating in verification.""" + + qr_data: Optional[str] = FieldInfo(alias="qrData", default=None) + """QR code payload to display for verification.""" + + sas: Optional[VerificationSas] = None + """Emoji or number comparison data for verification.""" + + supports_sas: Optional[bool] = FieldInfo(alias="supportsSAS", default=None) + """Whether emoji comparison is available.""" + + supports_scan_qr_code: Optional[bool] = FieldInfo(alias="supportsScanQRCode", default=None) + """Whether QR code verification is available.""" + + verification_id: Optional[str] = FieldInfo(alias="verificationID", default=None) + """Verification ID to pass in verification action paths.""" + + +class AppStateSnapshot(BaseModel): + e2ee: E2ee + """Encrypted messaging setup status.""" + + state: Literal[ + "needs-login", + "initializing", + "needs-cross-signing-setup", + "needs-verification", + "needs-secrets", + "needs-first-sync", + "ready", + ] + """Current onboarding state for Beeper Desktop.""" + + matrix: Optional[Matrix] = None + """Signed-in account details. Omitted until sign-in is complete.""" + + verification: Optional[Verification] = None + """Trusted-device verification progress.""" diff --git a/tests/api_resources/app/__init__.py b/tests/api_resources/app/__init__.py new file mode 100644 index 0000000..fd8019a --- /dev/null +++ b/tests/api_resources/app/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/app/e2ee/__init__.py b/tests/api_resources/app/e2ee/__init__.py new file mode 100644 index 0000000..fd8019a --- /dev/null +++ b/tests/api_resources/app/e2ee/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/app/e2ee/recovery_code/__init__.py b/tests/api_resources/app/e2ee/recovery_code/__init__.py new file mode 100644 index 0000000..fd8019a --- /dev/null +++ b/tests/api_resources/app/e2ee/recovery_code/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/app/e2ee/recovery_code/test_reset.py b/tests/api_resources/app/e2ee/recovery_code/test_reset.py new file mode 100644 index 0000000..34aae1f --- /dev/null +++ b/tests/api_resources/app/e2ee/recovery_code/test_reset.py @@ -0,0 +1,153 @@ +# 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 tests.utils import assert_matches_type +from beeper_desktop_api import BeeperDesktop, AsyncBeeperDesktop +from beeper_desktop_api.types.app.e2ee.recovery_code import ( + ResetCreateResponse, + ResetConfirmResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestReset: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: BeeperDesktop) -> None: + reset = client.app.e2ee.recovery_code.reset.create() + assert_matches_type(ResetCreateResponse, reset, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: BeeperDesktop) -> None: + reset = client.app.e2ee.recovery_code.reset.create( + recovery_code="recoveryCode", + ) + assert_matches_type(ResetCreateResponse, reset, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: BeeperDesktop) -> None: + response = client.app.e2ee.recovery_code.reset.with_raw_response.create() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + reset = response.parse() + assert_matches_type(ResetCreateResponse, reset, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: BeeperDesktop) -> None: + with client.app.e2ee.recovery_code.reset.with_streaming_response.create() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + reset = response.parse() + assert_matches_type(ResetCreateResponse, reset, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_method_confirm(self, client: BeeperDesktop) -> None: + reset = client.app.e2ee.recovery_code.reset.confirm( + recovery_code="x", + ) + assert_matches_type(ResetConfirmResponse, reset, path=["response"]) + + @parametrize + def test_raw_response_confirm(self, client: BeeperDesktop) -> None: + response = client.app.e2ee.recovery_code.reset.with_raw_response.confirm( + recovery_code="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + reset = response.parse() + assert_matches_type(ResetConfirmResponse, reset, path=["response"]) + + @parametrize + def test_streaming_response_confirm(self, client: BeeperDesktop) -> None: + with client.app.e2ee.recovery_code.reset.with_streaming_response.confirm( + recovery_code="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + reset = response.parse() + assert_matches_type(ResetConfirmResponse, reset, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncReset: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create(self, async_client: AsyncBeeperDesktop) -> None: + reset = await async_client.app.e2ee.recovery_code.reset.create() + assert_matches_type(ResetCreateResponse, reset, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncBeeperDesktop) -> None: + reset = await async_client.app.e2ee.recovery_code.reset.create( + recovery_code="recoveryCode", + ) + assert_matches_type(ResetCreateResponse, reset, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.app.e2ee.recovery_code.reset.with_raw_response.create() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + reset = await response.parse() + assert_matches_type(ResetCreateResponse, reset, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.app.e2ee.recovery_code.reset.with_streaming_response.create() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + reset = await response.parse() + assert_matches_type(ResetCreateResponse, reset, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_method_confirm(self, async_client: AsyncBeeperDesktop) -> None: + reset = await async_client.app.e2ee.recovery_code.reset.confirm( + recovery_code="x", + ) + assert_matches_type(ResetConfirmResponse, reset, path=["response"]) + + @parametrize + async def test_raw_response_confirm(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.app.e2ee.recovery_code.reset.with_raw_response.confirm( + recovery_code="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + reset = await response.parse() + assert_matches_type(ResetConfirmResponse, reset, path=["response"]) + + @parametrize + async def test_streaming_response_confirm(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.app.e2ee.recovery_code.reset.with_streaming_response.confirm( + recovery_code="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + reset = await response.parse() + assert_matches_type(ResetConfirmResponse, reset, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/app/e2ee/test_recovery_code.py b/tests/api_resources/app/e2ee/test_recovery_code.py new file mode 100644 index 0000000..c7caaf9 --- /dev/null +++ b/tests/api_resources/app/e2ee/test_recovery_code.py @@ -0,0 +1,139 @@ +# 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 tests.utils import assert_matches_type +from beeper_desktop_api import BeeperDesktop, AsyncBeeperDesktop +from beeper_desktop_api.types.app.e2ee import ( + RecoveryCodeVerifyResponse, + RecoveryCodeMarkBackedUpResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestRecoveryCode: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_mark_backed_up(self, client: BeeperDesktop) -> None: + recovery_code = client.app.e2ee.recovery_code.mark_backed_up() + assert_matches_type(RecoveryCodeMarkBackedUpResponse, recovery_code, path=["response"]) + + @parametrize + def test_raw_response_mark_backed_up(self, client: BeeperDesktop) -> None: + response = client.app.e2ee.recovery_code.with_raw_response.mark_backed_up() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + recovery_code = response.parse() + assert_matches_type(RecoveryCodeMarkBackedUpResponse, recovery_code, path=["response"]) + + @parametrize + def test_streaming_response_mark_backed_up(self, client: BeeperDesktop) -> None: + with client.app.e2ee.recovery_code.with_streaming_response.mark_backed_up() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + recovery_code = response.parse() + assert_matches_type(RecoveryCodeMarkBackedUpResponse, recovery_code, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_method_verify(self, client: BeeperDesktop) -> None: + recovery_code = client.app.e2ee.recovery_code.verify( + recovery_code="x", + ) + assert_matches_type(RecoveryCodeVerifyResponse, recovery_code, path=["response"]) + + @parametrize + def test_raw_response_verify(self, client: BeeperDesktop) -> None: + response = client.app.e2ee.recovery_code.with_raw_response.verify( + recovery_code="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + recovery_code = response.parse() + assert_matches_type(RecoveryCodeVerifyResponse, recovery_code, path=["response"]) + + @parametrize + def test_streaming_response_verify(self, client: BeeperDesktop) -> None: + with client.app.e2ee.recovery_code.with_streaming_response.verify( + recovery_code="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + recovery_code = response.parse() + assert_matches_type(RecoveryCodeVerifyResponse, recovery_code, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncRecoveryCode: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_mark_backed_up(self, async_client: AsyncBeeperDesktop) -> None: + recovery_code = await async_client.app.e2ee.recovery_code.mark_backed_up() + assert_matches_type(RecoveryCodeMarkBackedUpResponse, recovery_code, path=["response"]) + + @parametrize + async def test_raw_response_mark_backed_up(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.app.e2ee.recovery_code.with_raw_response.mark_backed_up() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + recovery_code = await response.parse() + assert_matches_type(RecoveryCodeMarkBackedUpResponse, recovery_code, path=["response"]) + + @parametrize + async def test_streaming_response_mark_backed_up(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.app.e2ee.recovery_code.with_streaming_response.mark_backed_up() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + recovery_code = await response.parse() + assert_matches_type(RecoveryCodeMarkBackedUpResponse, recovery_code, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_method_verify(self, async_client: AsyncBeeperDesktop) -> None: + recovery_code = await async_client.app.e2ee.recovery_code.verify( + recovery_code="x", + ) + assert_matches_type(RecoveryCodeVerifyResponse, recovery_code, path=["response"]) + + @parametrize + async def test_raw_response_verify(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.app.e2ee.recovery_code.with_raw_response.verify( + recovery_code="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + recovery_code = await response.parse() + assert_matches_type(RecoveryCodeVerifyResponse, recovery_code, path=["response"]) + + @parametrize + async def test_streaming_response_verify(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.app.e2ee.recovery_code.with_streaming_response.verify( + recovery_code="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + recovery_code = await response.parse() + assert_matches_type(RecoveryCodeVerifyResponse, recovery_code, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/app/e2ee/test_verification.py b/tests/api_resources/app/e2ee/test_verification.py new file mode 100644 index 0000000..1700f2d --- /dev/null +++ b/tests/api_resources/app/e2ee/test_verification.py @@ -0,0 +1,262 @@ +# 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 tests.utils import assert_matches_type +from beeper_desktop_api import BeeperDesktop, AsyncBeeperDesktop +from beeper_desktop_api.types.app.e2ee import ( + VerificationAcceptResponse, + VerificationCancelResponse, + VerificationCreateResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestVerification: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: BeeperDesktop) -> None: + verification = client.app.e2ee.verification.create() + assert_matches_type(VerificationCreateResponse, verification, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: BeeperDesktop) -> None: + verification = client.app.e2ee.verification.create( + user_id="userID", + ) + assert_matches_type(VerificationCreateResponse, verification, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: BeeperDesktop) -> None: + response = client.app.e2ee.verification.with_raw_response.create() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + verification = response.parse() + assert_matches_type(VerificationCreateResponse, verification, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: BeeperDesktop) -> None: + with client.app.e2ee.verification.with_streaming_response.create() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + verification = response.parse() + assert_matches_type(VerificationCreateResponse, verification, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_method_accept(self, client: BeeperDesktop) -> None: + verification = client.app.e2ee.verification.accept( + "x", + ) + assert_matches_type(VerificationAcceptResponse, verification, path=["response"]) + + @parametrize + def test_raw_response_accept(self, client: BeeperDesktop) -> None: + response = client.app.e2ee.verification.with_raw_response.accept( + "x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + verification = response.parse() + assert_matches_type(VerificationAcceptResponse, verification, path=["response"]) + + @parametrize + def test_streaming_response_accept(self, client: BeeperDesktop) -> None: + with client.app.e2ee.verification.with_streaming_response.accept( + "x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + verification = response.parse() + assert_matches_type(VerificationAcceptResponse, verification, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_accept(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `verification_id` but received ''"): + client.app.e2ee.verification.with_raw_response.accept( + "", + ) + + @parametrize + def test_method_cancel(self, client: BeeperDesktop) -> None: + verification = client.app.e2ee.verification.cancel( + verification_id="x", + ) + assert_matches_type(VerificationCancelResponse, verification, path=["response"]) + + @parametrize + def test_method_cancel_with_all_params(self, client: BeeperDesktop) -> None: + verification = client.app.e2ee.verification.cancel( + verification_id="x", + code="code", + reason="reason", + ) + assert_matches_type(VerificationCancelResponse, verification, path=["response"]) + + @parametrize + def test_raw_response_cancel(self, client: BeeperDesktop) -> None: + response = client.app.e2ee.verification.with_raw_response.cancel( + verification_id="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + verification = response.parse() + assert_matches_type(VerificationCancelResponse, verification, path=["response"]) + + @parametrize + def test_streaming_response_cancel(self, client: BeeperDesktop) -> None: + with client.app.e2ee.verification.with_streaming_response.cancel( + verification_id="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + verification = response.parse() + assert_matches_type(VerificationCancelResponse, verification, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_cancel(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `verification_id` but received ''"): + client.app.e2ee.verification.with_raw_response.cancel( + verification_id="", + ) + + +class TestAsyncVerification: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create(self, async_client: AsyncBeeperDesktop) -> None: + verification = await async_client.app.e2ee.verification.create() + assert_matches_type(VerificationCreateResponse, verification, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncBeeperDesktop) -> None: + verification = await async_client.app.e2ee.verification.create( + user_id="userID", + ) + assert_matches_type(VerificationCreateResponse, verification, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.app.e2ee.verification.with_raw_response.create() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + verification = await response.parse() + assert_matches_type(VerificationCreateResponse, verification, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.app.e2ee.verification.with_streaming_response.create() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + verification = await response.parse() + assert_matches_type(VerificationCreateResponse, verification, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_method_accept(self, async_client: AsyncBeeperDesktop) -> None: + verification = await async_client.app.e2ee.verification.accept( + "x", + ) + assert_matches_type(VerificationAcceptResponse, verification, path=["response"]) + + @parametrize + async def test_raw_response_accept(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.app.e2ee.verification.with_raw_response.accept( + "x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + verification = await response.parse() + assert_matches_type(VerificationAcceptResponse, verification, path=["response"]) + + @parametrize + async def test_streaming_response_accept(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.app.e2ee.verification.with_streaming_response.accept( + "x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + verification = await response.parse() + assert_matches_type(VerificationAcceptResponse, verification, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_accept(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `verification_id` but received ''"): + await async_client.app.e2ee.verification.with_raw_response.accept( + "", + ) + + @parametrize + async def test_method_cancel(self, async_client: AsyncBeeperDesktop) -> None: + verification = await async_client.app.e2ee.verification.cancel( + verification_id="x", + ) + assert_matches_type(VerificationCancelResponse, verification, path=["response"]) + + @parametrize + async def test_method_cancel_with_all_params(self, async_client: AsyncBeeperDesktop) -> None: + verification = await async_client.app.e2ee.verification.cancel( + verification_id="x", + code="code", + reason="reason", + ) + assert_matches_type(VerificationCancelResponse, verification, path=["response"]) + + @parametrize + async def test_raw_response_cancel(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.app.e2ee.verification.with_raw_response.cancel( + verification_id="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + verification = await response.parse() + assert_matches_type(VerificationCancelResponse, verification, path=["response"]) + + @parametrize + async def test_streaming_response_cancel(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.app.e2ee.verification.with_streaming_response.cancel( + verification_id="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + verification = await response.parse() + assert_matches_type(VerificationCancelResponse, verification, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_cancel(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `verification_id` but received ''"): + await async_client.app.e2ee.verification.with_raw_response.cancel( + verification_id="", + ) diff --git a/tests/api_resources/app/e2ee/verification/__init__.py b/tests/api_resources/app/e2ee/verification/__init__.py new file mode 100644 index 0000000..fd8019a --- /dev/null +++ b/tests/api_resources/app/e2ee/verification/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/app/e2ee/verification/test_qr.py b/tests/api_resources/app/e2ee/verification/test_qr.py new file mode 100644 index 0000000..9eb8e0c --- /dev/null +++ b/tests/api_resources/app/e2ee/verification/test_qr.py @@ -0,0 +1,162 @@ +# 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 tests.utils import assert_matches_type +from beeper_desktop_api import BeeperDesktop, AsyncBeeperDesktop +from beeper_desktop_api.types.app.e2ee.verification import QrScanResponse, QrConfirmScannedResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestQr: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_confirm_scanned(self, client: BeeperDesktop) -> None: + qr = client.app.e2ee.verification.qr.confirm_scanned( + "x", + ) + assert_matches_type(QrConfirmScannedResponse, qr, path=["response"]) + + @parametrize + def test_raw_response_confirm_scanned(self, client: BeeperDesktop) -> None: + response = client.app.e2ee.verification.qr.with_raw_response.confirm_scanned( + "x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + qr = response.parse() + assert_matches_type(QrConfirmScannedResponse, qr, path=["response"]) + + @parametrize + def test_streaming_response_confirm_scanned(self, client: BeeperDesktop) -> None: + with client.app.e2ee.verification.qr.with_streaming_response.confirm_scanned( + "x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + qr = response.parse() + assert_matches_type(QrConfirmScannedResponse, qr, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_confirm_scanned(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `verification_id` but received ''"): + client.app.e2ee.verification.qr.with_raw_response.confirm_scanned( + "", + ) + + @parametrize + def test_method_scan(self, client: BeeperDesktop) -> None: + qr = client.app.e2ee.verification.qr.scan( + data="x", + ) + assert_matches_type(QrScanResponse, qr, path=["response"]) + + @parametrize + def test_raw_response_scan(self, client: BeeperDesktop) -> None: + response = client.app.e2ee.verification.qr.with_raw_response.scan( + data="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + qr = response.parse() + assert_matches_type(QrScanResponse, qr, path=["response"]) + + @parametrize + def test_streaming_response_scan(self, client: BeeperDesktop) -> None: + with client.app.e2ee.verification.qr.with_streaming_response.scan( + data="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + qr = response.parse() + assert_matches_type(QrScanResponse, qr, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncQr: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_confirm_scanned(self, async_client: AsyncBeeperDesktop) -> None: + qr = await async_client.app.e2ee.verification.qr.confirm_scanned( + "x", + ) + assert_matches_type(QrConfirmScannedResponse, qr, path=["response"]) + + @parametrize + async def test_raw_response_confirm_scanned(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.app.e2ee.verification.qr.with_raw_response.confirm_scanned( + "x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + qr = await response.parse() + assert_matches_type(QrConfirmScannedResponse, qr, path=["response"]) + + @parametrize + async def test_streaming_response_confirm_scanned(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.app.e2ee.verification.qr.with_streaming_response.confirm_scanned( + "x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + qr = await response.parse() + assert_matches_type(QrConfirmScannedResponse, qr, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_confirm_scanned(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `verification_id` but received ''"): + await async_client.app.e2ee.verification.qr.with_raw_response.confirm_scanned( + "", + ) + + @parametrize + async def test_method_scan(self, async_client: AsyncBeeperDesktop) -> None: + qr = await async_client.app.e2ee.verification.qr.scan( + data="x", + ) + assert_matches_type(QrScanResponse, qr, path=["response"]) + + @parametrize + async def test_raw_response_scan(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.app.e2ee.verification.qr.with_raw_response.scan( + data="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + qr = await response.parse() + assert_matches_type(QrScanResponse, qr, path=["response"]) + + @parametrize + async def test_streaming_response_scan(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.app.e2ee.verification.qr.with_streaming_response.scan( + data="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + qr = await response.parse() + assert_matches_type(QrScanResponse, qr, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/app/e2ee/verification/test_sas.py b/tests/api_resources/app/e2ee/verification/test_sas.py new file mode 100644 index 0000000..7a8c43c --- /dev/null +++ b/tests/api_resources/app/e2ee/verification/test_sas.py @@ -0,0 +1,176 @@ +# 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 tests.utils import assert_matches_type +from beeper_desktop_api import BeeperDesktop, AsyncBeeperDesktop +from beeper_desktop_api.types.app.e2ee.verification import SaStartResponse, SaConfirmResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestSas: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_confirm(self, client: BeeperDesktop) -> None: + sa = client.app.e2ee.verification.sas.confirm( + "x", + ) + assert_matches_type(SaConfirmResponse, sa, path=["response"]) + + @parametrize + def test_raw_response_confirm(self, client: BeeperDesktop) -> None: + response = client.app.e2ee.verification.sas.with_raw_response.confirm( + "x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + sa = response.parse() + assert_matches_type(SaConfirmResponse, sa, path=["response"]) + + @parametrize + def test_streaming_response_confirm(self, client: BeeperDesktop) -> None: + with client.app.e2ee.verification.sas.with_streaming_response.confirm( + "x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + sa = response.parse() + assert_matches_type(SaConfirmResponse, sa, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_confirm(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `verification_id` but received ''"): + client.app.e2ee.verification.sas.with_raw_response.confirm( + "", + ) + + @parametrize + def test_method_start(self, client: BeeperDesktop) -> None: + sa = client.app.e2ee.verification.sas.start( + "x", + ) + assert_matches_type(SaStartResponse, sa, path=["response"]) + + @parametrize + def test_raw_response_start(self, client: BeeperDesktop) -> None: + response = client.app.e2ee.verification.sas.with_raw_response.start( + "x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + sa = response.parse() + assert_matches_type(SaStartResponse, sa, path=["response"]) + + @parametrize + def test_streaming_response_start(self, client: BeeperDesktop) -> None: + with client.app.e2ee.verification.sas.with_streaming_response.start( + "x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + sa = response.parse() + assert_matches_type(SaStartResponse, sa, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_start(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `verification_id` but received ''"): + client.app.e2ee.verification.sas.with_raw_response.start( + "", + ) + + +class TestAsyncSas: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_confirm(self, async_client: AsyncBeeperDesktop) -> None: + sa = await async_client.app.e2ee.verification.sas.confirm( + "x", + ) + assert_matches_type(SaConfirmResponse, sa, path=["response"]) + + @parametrize + async def test_raw_response_confirm(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.app.e2ee.verification.sas.with_raw_response.confirm( + "x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + sa = await response.parse() + assert_matches_type(SaConfirmResponse, sa, path=["response"]) + + @parametrize + async def test_streaming_response_confirm(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.app.e2ee.verification.sas.with_streaming_response.confirm( + "x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + sa = await response.parse() + assert_matches_type(SaConfirmResponse, sa, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_confirm(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `verification_id` but received ''"): + await async_client.app.e2ee.verification.sas.with_raw_response.confirm( + "", + ) + + @parametrize + async def test_method_start(self, async_client: AsyncBeeperDesktop) -> None: + sa = await async_client.app.e2ee.verification.sas.start( + "x", + ) + assert_matches_type(SaStartResponse, sa, path=["response"]) + + @parametrize + async def test_raw_response_start(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.app.e2ee.verification.sas.with_raw_response.start( + "x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + sa = await response.parse() + assert_matches_type(SaStartResponse, sa, path=["response"]) + + @parametrize + async def test_streaming_response_start(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.app.e2ee.verification.sas.with_streaming_response.start( + "x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + sa = await response.parse() + assert_matches_type(SaStartResponse, sa, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_start(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `verification_id` but received ''"): + await async_client.app.e2ee.verification.sas.with_raw_response.start( + "", + ) diff --git a/tests/api_resources/app/test_login.py b/tests/api_resources/app/test_login.py new file mode 100644 index 0000000..7963136 --- /dev/null +++ b/tests/api_resources/app/test_login.py @@ -0,0 +1,294 @@ +# 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 tests.utils import assert_matches_type +from beeper_desktop_api import BeeperDesktop, AsyncBeeperDesktop +from beeper_desktop_api.types.app import ( + LoginStartResponse, + LoginRegisterResponse, + LoginResponseResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestLogin: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_email(self, client: BeeperDesktop) -> None: + login = client.app.login.email( + email="dev@stainless.com", + request="request", + ) + assert_matches_type(object, login, path=["response"]) + + @parametrize + def test_raw_response_email(self, client: BeeperDesktop) -> None: + response = client.app.login.with_raw_response.email( + email="dev@stainless.com", + request="request", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + login = response.parse() + assert_matches_type(object, login, path=["response"]) + + @parametrize + def test_streaming_response_email(self, client: BeeperDesktop) -> None: + with client.app.login.with_streaming_response.email( + email="dev@stainless.com", + request="request", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + login = response.parse() + assert_matches_type(object, login, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_method_register(self, client: BeeperDesktop) -> None: + login = client.app.login.register( + accept_terms=True, + lead_token="leadToken", + request="request", + username="x", + ) + assert_matches_type(LoginRegisterResponse, login, path=["response"]) + + @parametrize + def test_raw_response_register(self, client: BeeperDesktop) -> None: + response = client.app.login.with_raw_response.register( + accept_terms=True, + lead_token="leadToken", + request="request", + username="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + login = response.parse() + assert_matches_type(LoginRegisterResponse, login, path=["response"]) + + @parametrize + def test_streaming_response_register(self, client: BeeperDesktop) -> None: + with client.app.login.with_streaming_response.register( + accept_terms=True, + lead_token="leadToken", + request="request", + username="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + login = response.parse() + assert_matches_type(LoginRegisterResponse, login, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_method_response(self, client: BeeperDesktop) -> None: + login = client.app.login.response( + request="request", + response="response", + ) + assert_matches_type(LoginResponseResponse, login, path=["response"]) + + @parametrize + def test_raw_response_response(self, client: BeeperDesktop) -> None: + response = client.app.login.with_raw_response.response( + request="request", + response="response", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + login = response.parse() + assert_matches_type(LoginResponseResponse, login, path=["response"]) + + @parametrize + def test_streaming_response_response(self, client: BeeperDesktop) -> None: + with client.app.login.with_streaming_response.response( + request="request", + response="response", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + login = response.parse() + assert_matches_type(LoginResponseResponse, login, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_method_start(self, client: BeeperDesktop) -> None: + login = client.app.login.start() + assert_matches_type(LoginStartResponse, login, path=["response"]) + + @parametrize + def test_raw_response_start(self, client: BeeperDesktop) -> None: + response = client.app.login.with_raw_response.start() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + login = response.parse() + assert_matches_type(LoginStartResponse, login, path=["response"]) + + @parametrize + def test_streaming_response_start(self, client: BeeperDesktop) -> None: + with client.app.login.with_streaming_response.start() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + login = response.parse() + assert_matches_type(LoginStartResponse, login, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncLogin: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_email(self, async_client: AsyncBeeperDesktop) -> None: + login = await async_client.app.login.email( + email="dev@stainless.com", + request="request", + ) + assert_matches_type(object, login, path=["response"]) + + @parametrize + async def test_raw_response_email(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.app.login.with_raw_response.email( + email="dev@stainless.com", + request="request", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + login = await response.parse() + assert_matches_type(object, login, path=["response"]) + + @parametrize + async def test_streaming_response_email(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.app.login.with_streaming_response.email( + email="dev@stainless.com", + request="request", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + login = await response.parse() + assert_matches_type(object, login, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_method_register(self, async_client: AsyncBeeperDesktop) -> None: + login = await async_client.app.login.register( + accept_terms=True, + lead_token="leadToken", + request="request", + username="x", + ) + assert_matches_type(LoginRegisterResponse, login, path=["response"]) + + @parametrize + async def test_raw_response_register(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.app.login.with_raw_response.register( + accept_terms=True, + lead_token="leadToken", + request="request", + username="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + login = await response.parse() + assert_matches_type(LoginRegisterResponse, login, path=["response"]) + + @parametrize + async def test_streaming_response_register(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.app.login.with_streaming_response.register( + accept_terms=True, + lead_token="leadToken", + request="request", + username="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + login = await response.parse() + assert_matches_type(LoginRegisterResponse, login, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_method_response(self, async_client: AsyncBeeperDesktop) -> None: + login = await async_client.app.login.response( + request="request", + response="response", + ) + assert_matches_type(LoginResponseResponse, login, path=["response"]) + + @parametrize + async def test_raw_response_response(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.app.login.with_raw_response.response( + request="request", + response="response", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + login = await response.parse() + assert_matches_type(LoginResponseResponse, login, path=["response"]) + + @parametrize + async def test_streaming_response_response(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.app.login.with_streaming_response.response( + request="request", + response="response", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + login = await response.parse() + assert_matches_type(LoginResponseResponse, login, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_method_start(self, async_client: AsyncBeeperDesktop) -> None: + login = await async_client.app.login.start() + assert_matches_type(LoginStartResponse, login, path=["response"]) + + @parametrize + async def test_raw_response_start(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.app.login.with_raw_response.start() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + login = await response.parse() + assert_matches_type(LoginStartResponse, login, path=["response"]) + + @parametrize + async def test_streaming_response_start(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.app.login.with_streaming_response.start() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + login = await response.parse() + assert_matches_type(LoginStartResponse, login, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/matrix/__init__.py b/tests/api_resources/matrix/__init__.py new file mode 100644 index 0000000..fd8019a --- /dev/null +++ b/tests/api_resources/matrix/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/matrix/bridges/__init__.py b/tests/api_resources/matrix/bridges/__init__.py new file mode 100644 index 0000000..fd8019a --- /dev/null +++ b/tests/api_resources/matrix/bridges/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/matrix/bridges/test_auth.py b/tests/api_resources/matrix/bridges/test_auth.py new file mode 100644 index 0000000..bdb57e4 --- /dev/null +++ b/tests/api_resources/matrix/bridges/test_auth.py @@ -0,0 +1,854 @@ +# 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 tests.utils import assert_matches_type +from beeper_desktop_api import BeeperDesktop, AsyncBeeperDesktop +from beeper_desktop_api.types.matrix.bridges import ( + AuthWhoamiResponse, + AuthListFlowsResponse, + AuthListLoginsResponse, + AuthStartLoginResponse, + AuthWaitForStepResponse, + AuthSubmitCookiesResponse, + AuthSubmitUserInputResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestAuth: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_list_flows(self, client: BeeperDesktop) -> None: + auth = client.matrix.bridges.auth.list_flows( + "bridgeID", + ) + assert_matches_type(AuthListFlowsResponse, auth, path=["response"]) + + @parametrize + def test_raw_response_list_flows(self, client: BeeperDesktop) -> None: + response = client.matrix.bridges.auth.with_raw_response.list_flows( + "bridgeID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + auth = response.parse() + assert_matches_type(AuthListFlowsResponse, auth, path=["response"]) + + @parametrize + def test_streaming_response_list_flows(self, client: BeeperDesktop) -> None: + with client.matrix.bridges.auth.with_streaming_response.list_flows( + "bridgeID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + auth = response.parse() + assert_matches_type(AuthListFlowsResponse, auth, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list_flows(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + client.matrix.bridges.auth.with_raw_response.list_flows( + "", + ) + + @parametrize + def test_method_list_logins(self, client: BeeperDesktop) -> None: + auth = client.matrix.bridges.auth.list_logins( + "bridgeID", + ) + assert_matches_type(AuthListLoginsResponse, auth, path=["response"]) + + @parametrize + def test_raw_response_list_logins(self, client: BeeperDesktop) -> None: + response = client.matrix.bridges.auth.with_raw_response.list_logins( + "bridgeID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + auth = response.parse() + assert_matches_type(AuthListLoginsResponse, auth, path=["response"]) + + @parametrize + def test_streaming_response_list_logins(self, client: BeeperDesktop) -> None: + with client.matrix.bridges.auth.with_streaming_response.list_logins( + "bridgeID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + auth = response.parse() + assert_matches_type(AuthListLoginsResponse, auth, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list_logins(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + client.matrix.bridges.auth.with_raw_response.list_logins( + "", + ) + + @parametrize + def test_method_logout(self, client: BeeperDesktop) -> None: + auth = client.matrix.bridges.auth.logout( + login_id="bcc68892-b180-414f-9516-b4aadf7d0496", + bridge_id="bridgeID", + ) + assert_matches_type(object, auth, path=["response"]) + + @parametrize + def test_raw_response_logout(self, client: BeeperDesktop) -> None: + response = client.matrix.bridges.auth.with_raw_response.logout( + login_id="bcc68892-b180-414f-9516-b4aadf7d0496", + bridge_id="bridgeID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + auth = response.parse() + assert_matches_type(object, auth, path=["response"]) + + @parametrize + def test_streaming_response_logout(self, client: BeeperDesktop) -> None: + with client.matrix.bridges.auth.with_streaming_response.logout( + login_id="bcc68892-b180-414f-9516-b4aadf7d0496", + bridge_id="bridgeID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + auth = response.parse() + assert_matches_type(object, auth, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_logout(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + client.matrix.bridges.auth.with_raw_response.logout( + login_id="bcc68892-b180-414f-9516-b4aadf7d0496", + bridge_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `login_id` but received ''"): + client.matrix.bridges.auth.with_raw_response.logout( + login_id="", + bridge_id="bridgeID", + ) + + @parametrize + def test_method_start_login(self, client: BeeperDesktop) -> None: + auth = client.matrix.bridges.auth.start_login( + flow_id="qr", + bridge_id="bridgeID", + ) + assert_matches_type(AuthStartLoginResponse, auth, path=["response"]) + + @parametrize + def test_method_start_login_with_all_params(self, client: BeeperDesktop) -> None: + auth = client.matrix.bridges.auth.start_login( + flow_id="qr", + bridge_id="bridgeID", + login_id="bcc68892-b180-414f-9516-b4aadf7d0496", + ) + assert_matches_type(AuthStartLoginResponse, auth, path=["response"]) + + @parametrize + def test_raw_response_start_login(self, client: BeeperDesktop) -> None: + response = client.matrix.bridges.auth.with_raw_response.start_login( + flow_id="qr", + bridge_id="bridgeID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + auth = response.parse() + assert_matches_type(AuthStartLoginResponse, auth, path=["response"]) + + @parametrize + def test_streaming_response_start_login(self, client: BeeperDesktop) -> None: + with client.matrix.bridges.auth.with_streaming_response.start_login( + flow_id="qr", + bridge_id="bridgeID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + auth = response.parse() + assert_matches_type(AuthStartLoginResponse, auth, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_start_login(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + client.matrix.bridges.auth.with_raw_response.start_login( + flow_id="qr", + bridge_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `flow_id` but received ''"): + client.matrix.bridges.auth.with_raw_response.start_login( + flow_id="", + bridge_id="bridgeID", + ) + + @parametrize + def test_method_submit_cookies(self, client: BeeperDesktop) -> None: + auth = client.matrix.bridges.auth.submit_cookies( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="loginProcessID", + body={"foo": "string"}, + ) + assert_matches_type(AuthSubmitCookiesResponse, auth, path=["response"]) + + @parametrize + def test_raw_response_submit_cookies(self, client: BeeperDesktop) -> None: + response = client.matrix.bridges.auth.with_raw_response.submit_cookies( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="loginProcessID", + body={"foo": "string"}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + auth = response.parse() + assert_matches_type(AuthSubmitCookiesResponse, auth, path=["response"]) + + @parametrize + def test_streaming_response_submit_cookies(self, client: BeeperDesktop) -> None: + with client.matrix.bridges.auth.with_streaming_response.submit_cookies( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="loginProcessID", + body={"foo": "string"}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + auth = response.parse() + assert_matches_type(AuthSubmitCookiesResponse, auth, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_submit_cookies(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + client.matrix.bridges.auth.with_raw_response.submit_cookies( + step_id="stepID", + bridge_id="", + login_process_id="loginProcessID", + body={"foo": "string"}, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `login_process_id` but received ''"): + client.matrix.bridges.auth.with_raw_response.submit_cookies( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="", + body={"foo": "string"}, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `step_id` but received ''"): + client.matrix.bridges.auth.with_raw_response.submit_cookies( + step_id="", + bridge_id="bridgeID", + login_process_id="loginProcessID", + body={"foo": "string"}, + ) + + @parametrize + def test_method_submit_user_input(self, client: BeeperDesktop) -> None: + auth = client.matrix.bridges.auth.submit_user_input( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="loginProcessID", + body={"foo": "string"}, + ) + assert_matches_type(AuthSubmitUserInputResponse, auth, path=["response"]) + + @parametrize + def test_raw_response_submit_user_input(self, client: BeeperDesktop) -> None: + response = client.matrix.bridges.auth.with_raw_response.submit_user_input( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="loginProcessID", + body={"foo": "string"}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + auth = response.parse() + assert_matches_type(AuthSubmitUserInputResponse, auth, path=["response"]) + + @parametrize + def test_streaming_response_submit_user_input(self, client: BeeperDesktop) -> None: + with client.matrix.bridges.auth.with_streaming_response.submit_user_input( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="loginProcessID", + body={"foo": "string"}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + auth = response.parse() + assert_matches_type(AuthSubmitUserInputResponse, auth, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_submit_user_input(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + client.matrix.bridges.auth.with_raw_response.submit_user_input( + step_id="stepID", + bridge_id="", + login_process_id="loginProcessID", + body={"foo": "string"}, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `login_process_id` but received ''"): + client.matrix.bridges.auth.with_raw_response.submit_user_input( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="", + body={"foo": "string"}, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `step_id` but received ''"): + client.matrix.bridges.auth.with_raw_response.submit_user_input( + step_id="", + bridge_id="bridgeID", + login_process_id="loginProcessID", + body={"foo": "string"}, + ) + + @parametrize + def test_method_wait_for_step(self, client: BeeperDesktop) -> None: + auth = client.matrix.bridges.auth.wait_for_step( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="loginProcessID", + ) + assert_matches_type(AuthWaitForStepResponse, auth, path=["response"]) + + @parametrize + def test_raw_response_wait_for_step(self, client: BeeperDesktop) -> None: + response = client.matrix.bridges.auth.with_raw_response.wait_for_step( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="loginProcessID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + auth = response.parse() + assert_matches_type(AuthWaitForStepResponse, auth, path=["response"]) + + @parametrize + def test_streaming_response_wait_for_step(self, client: BeeperDesktop) -> None: + with client.matrix.bridges.auth.with_streaming_response.wait_for_step( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="loginProcessID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + auth = response.parse() + assert_matches_type(AuthWaitForStepResponse, auth, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_wait_for_step(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + client.matrix.bridges.auth.with_raw_response.wait_for_step( + step_id="stepID", + bridge_id="", + login_process_id="loginProcessID", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `login_process_id` but received ''"): + client.matrix.bridges.auth.with_raw_response.wait_for_step( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `step_id` but received ''"): + client.matrix.bridges.auth.with_raw_response.wait_for_step( + step_id="", + bridge_id="bridgeID", + login_process_id="loginProcessID", + ) + + @parametrize + def test_method_whoami(self, client: BeeperDesktop) -> None: + auth = client.matrix.bridges.auth.whoami( + "bridgeID", + ) + assert_matches_type(AuthWhoamiResponse, auth, path=["response"]) + + @parametrize + def test_raw_response_whoami(self, client: BeeperDesktop) -> None: + response = client.matrix.bridges.auth.with_raw_response.whoami( + "bridgeID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + auth = response.parse() + assert_matches_type(AuthWhoamiResponse, auth, path=["response"]) + + @parametrize + def test_streaming_response_whoami(self, client: BeeperDesktop) -> None: + with client.matrix.bridges.auth.with_streaming_response.whoami( + "bridgeID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + auth = response.parse() + assert_matches_type(AuthWhoamiResponse, auth, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_whoami(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + client.matrix.bridges.auth.with_raw_response.whoami( + "", + ) + + +class TestAsyncAuth: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_list_flows(self, async_client: AsyncBeeperDesktop) -> None: + auth = await async_client.matrix.bridges.auth.list_flows( + "bridgeID", + ) + assert_matches_type(AuthListFlowsResponse, auth, path=["response"]) + + @parametrize + async def test_raw_response_list_flows(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.bridges.auth.with_raw_response.list_flows( + "bridgeID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + auth = await response.parse() + assert_matches_type(AuthListFlowsResponse, auth, path=["response"]) + + @parametrize + async def test_streaming_response_list_flows(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.bridges.auth.with_streaming_response.list_flows( + "bridgeID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + auth = await response.parse() + assert_matches_type(AuthListFlowsResponse, auth, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list_flows(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + await async_client.matrix.bridges.auth.with_raw_response.list_flows( + "", + ) + + @parametrize + async def test_method_list_logins(self, async_client: AsyncBeeperDesktop) -> None: + auth = await async_client.matrix.bridges.auth.list_logins( + "bridgeID", + ) + assert_matches_type(AuthListLoginsResponse, auth, path=["response"]) + + @parametrize + async def test_raw_response_list_logins(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.bridges.auth.with_raw_response.list_logins( + "bridgeID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + auth = await response.parse() + assert_matches_type(AuthListLoginsResponse, auth, path=["response"]) + + @parametrize + async def test_streaming_response_list_logins(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.bridges.auth.with_streaming_response.list_logins( + "bridgeID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + auth = await response.parse() + assert_matches_type(AuthListLoginsResponse, auth, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list_logins(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + await async_client.matrix.bridges.auth.with_raw_response.list_logins( + "", + ) + + @parametrize + async def test_method_logout(self, async_client: AsyncBeeperDesktop) -> None: + auth = await async_client.matrix.bridges.auth.logout( + login_id="bcc68892-b180-414f-9516-b4aadf7d0496", + bridge_id="bridgeID", + ) + assert_matches_type(object, auth, path=["response"]) + + @parametrize + async def test_raw_response_logout(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.bridges.auth.with_raw_response.logout( + login_id="bcc68892-b180-414f-9516-b4aadf7d0496", + bridge_id="bridgeID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + auth = await response.parse() + assert_matches_type(object, auth, path=["response"]) + + @parametrize + async def test_streaming_response_logout(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.bridges.auth.with_streaming_response.logout( + login_id="bcc68892-b180-414f-9516-b4aadf7d0496", + bridge_id="bridgeID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + auth = await response.parse() + assert_matches_type(object, auth, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_logout(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + await async_client.matrix.bridges.auth.with_raw_response.logout( + login_id="bcc68892-b180-414f-9516-b4aadf7d0496", + bridge_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `login_id` but received ''"): + await async_client.matrix.bridges.auth.with_raw_response.logout( + login_id="", + bridge_id="bridgeID", + ) + + @parametrize + async def test_method_start_login(self, async_client: AsyncBeeperDesktop) -> None: + auth = await async_client.matrix.bridges.auth.start_login( + flow_id="qr", + bridge_id="bridgeID", + ) + assert_matches_type(AuthStartLoginResponse, auth, path=["response"]) + + @parametrize + async def test_method_start_login_with_all_params(self, async_client: AsyncBeeperDesktop) -> None: + auth = await async_client.matrix.bridges.auth.start_login( + flow_id="qr", + bridge_id="bridgeID", + login_id="bcc68892-b180-414f-9516-b4aadf7d0496", + ) + assert_matches_type(AuthStartLoginResponse, auth, path=["response"]) + + @parametrize + async def test_raw_response_start_login(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.bridges.auth.with_raw_response.start_login( + flow_id="qr", + bridge_id="bridgeID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + auth = await response.parse() + assert_matches_type(AuthStartLoginResponse, auth, path=["response"]) + + @parametrize + async def test_streaming_response_start_login(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.bridges.auth.with_streaming_response.start_login( + flow_id="qr", + bridge_id="bridgeID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + auth = await response.parse() + assert_matches_type(AuthStartLoginResponse, auth, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_start_login(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + await async_client.matrix.bridges.auth.with_raw_response.start_login( + flow_id="qr", + bridge_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `flow_id` but received ''"): + await async_client.matrix.bridges.auth.with_raw_response.start_login( + flow_id="", + bridge_id="bridgeID", + ) + + @parametrize + async def test_method_submit_cookies(self, async_client: AsyncBeeperDesktop) -> None: + auth = await async_client.matrix.bridges.auth.submit_cookies( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="loginProcessID", + body={"foo": "string"}, + ) + assert_matches_type(AuthSubmitCookiesResponse, auth, path=["response"]) + + @parametrize + async def test_raw_response_submit_cookies(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.bridges.auth.with_raw_response.submit_cookies( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="loginProcessID", + body={"foo": "string"}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + auth = await response.parse() + assert_matches_type(AuthSubmitCookiesResponse, auth, path=["response"]) + + @parametrize + async def test_streaming_response_submit_cookies(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.bridges.auth.with_streaming_response.submit_cookies( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="loginProcessID", + body={"foo": "string"}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + auth = await response.parse() + assert_matches_type(AuthSubmitCookiesResponse, auth, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_submit_cookies(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + await async_client.matrix.bridges.auth.with_raw_response.submit_cookies( + step_id="stepID", + bridge_id="", + login_process_id="loginProcessID", + body={"foo": "string"}, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `login_process_id` but received ''"): + await async_client.matrix.bridges.auth.with_raw_response.submit_cookies( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="", + body={"foo": "string"}, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `step_id` but received ''"): + await async_client.matrix.bridges.auth.with_raw_response.submit_cookies( + step_id="", + bridge_id="bridgeID", + login_process_id="loginProcessID", + body={"foo": "string"}, + ) + + @parametrize + async def test_method_submit_user_input(self, async_client: AsyncBeeperDesktop) -> None: + auth = await async_client.matrix.bridges.auth.submit_user_input( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="loginProcessID", + body={"foo": "string"}, + ) + assert_matches_type(AuthSubmitUserInputResponse, auth, path=["response"]) + + @parametrize + async def test_raw_response_submit_user_input(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.bridges.auth.with_raw_response.submit_user_input( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="loginProcessID", + body={"foo": "string"}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + auth = await response.parse() + assert_matches_type(AuthSubmitUserInputResponse, auth, path=["response"]) + + @parametrize + async def test_streaming_response_submit_user_input(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.bridges.auth.with_streaming_response.submit_user_input( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="loginProcessID", + body={"foo": "string"}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + auth = await response.parse() + assert_matches_type(AuthSubmitUserInputResponse, auth, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_submit_user_input(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + await async_client.matrix.bridges.auth.with_raw_response.submit_user_input( + step_id="stepID", + bridge_id="", + login_process_id="loginProcessID", + body={"foo": "string"}, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `login_process_id` but received ''"): + await async_client.matrix.bridges.auth.with_raw_response.submit_user_input( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="", + body={"foo": "string"}, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `step_id` but received ''"): + await async_client.matrix.bridges.auth.with_raw_response.submit_user_input( + step_id="", + bridge_id="bridgeID", + login_process_id="loginProcessID", + body={"foo": "string"}, + ) + + @parametrize + async def test_method_wait_for_step(self, async_client: AsyncBeeperDesktop) -> None: + auth = await async_client.matrix.bridges.auth.wait_for_step( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="loginProcessID", + ) + assert_matches_type(AuthWaitForStepResponse, auth, path=["response"]) + + @parametrize + async def test_raw_response_wait_for_step(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.bridges.auth.with_raw_response.wait_for_step( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="loginProcessID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + auth = await response.parse() + assert_matches_type(AuthWaitForStepResponse, auth, path=["response"]) + + @parametrize + async def test_streaming_response_wait_for_step(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.bridges.auth.with_streaming_response.wait_for_step( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="loginProcessID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + auth = await response.parse() + assert_matches_type(AuthWaitForStepResponse, auth, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_wait_for_step(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + await async_client.matrix.bridges.auth.with_raw_response.wait_for_step( + step_id="stepID", + bridge_id="", + login_process_id="loginProcessID", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `login_process_id` but received ''"): + await async_client.matrix.bridges.auth.with_raw_response.wait_for_step( + step_id="stepID", + bridge_id="bridgeID", + login_process_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `step_id` but received ''"): + await async_client.matrix.bridges.auth.with_raw_response.wait_for_step( + step_id="", + bridge_id="bridgeID", + login_process_id="loginProcessID", + ) + + @parametrize + async def test_method_whoami(self, async_client: AsyncBeeperDesktop) -> None: + auth = await async_client.matrix.bridges.auth.whoami( + "bridgeID", + ) + assert_matches_type(AuthWhoamiResponse, auth, path=["response"]) + + @parametrize + async def test_raw_response_whoami(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.bridges.auth.with_raw_response.whoami( + "bridgeID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + auth = await response.parse() + assert_matches_type(AuthWhoamiResponse, auth, path=["response"]) + + @parametrize + async def test_streaming_response_whoami(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.bridges.auth.with_streaming_response.whoami( + "bridgeID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + auth = await response.parse() + assert_matches_type(AuthWhoamiResponse, auth, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_whoami(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + await async_client.matrix.bridges.auth.with_raw_response.whoami( + "", + ) diff --git a/tests/api_resources/matrix/bridges/test_capabilities.py b/tests/api_resources/matrix/bridges/test_capabilities.py new file mode 100644 index 0000000..c1c6fc7 --- /dev/null +++ b/tests/api_resources/matrix/bridges/test_capabilities.py @@ -0,0 +1,100 @@ +# 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 tests.utils import assert_matches_type +from beeper_desktop_api import BeeperDesktop, AsyncBeeperDesktop +from beeper_desktop_api.types.matrix.bridges import CapabilityRetrieveResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestCapabilities: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_retrieve(self, client: BeeperDesktop) -> None: + capability = client.matrix.bridges.capabilities.retrieve( + "bridgeID", + ) + assert_matches_type(CapabilityRetrieveResponse, capability, path=["response"]) + + @parametrize + def test_raw_response_retrieve(self, client: BeeperDesktop) -> None: + response = client.matrix.bridges.capabilities.with_raw_response.retrieve( + "bridgeID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + capability = response.parse() + assert_matches_type(CapabilityRetrieveResponse, capability, path=["response"]) + + @parametrize + def test_streaming_response_retrieve(self, client: BeeperDesktop) -> None: + with client.matrix.bridges.capabilities.with_streaming_response.retrieve( + "bridgeID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + capability = response.parse() + assert_matches_type(CapabilityRetrieveResponse, capability, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_retrieve(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + client.matrix.bridges.capabilities.with_raw_response.retrieve( + "", + ) + + +class TestAsyncCapabilities: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_retrieve(self, async_client: AsyncBeeperDesktop) -> None: + capability = await async_client.matrix.bridges.capabilities.retrieve( + "bridgeID", + ) + assert_matches_type(CapabilityRetrieveResponse, capability, path=["response"]) + + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.bridges.capabilities.with_raw_response.retrieve( + "bridgeID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + capability = await response.parse() + assert_matches_type(CapabilityRetrieveResponse, capability, path=["response"]) + + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.bridges.capabilities.with_streaming_response.retrieve( + "bridgeID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + capability = await response.parse() + assert_matches_type(CapabilityRetrieveResponse, capability, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + await async_client.matrix.bridges.capabilities.with_raw_response.retrieve( + "", + ) diff --git a/tests/api_resources/matrix/bridges/test_contacts.py b/tests/api_resources/matrix/bridges/test_contacts.py new file mode 100644 index 0000000..a5e9913 --- /dev/null +++ b/tests/api_resources/matrix/bridges/test_contacts.py @@ -0,0 +1,116 @@ +# 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 tests.utils import assert_matches_type +from beeper_desktop_api import BeeperDesktop, AsyncBeeperDesktop +from beeper_desktop_api.types.matrix.bridges import ContactListResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestContacts: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_list(self, client: BeeperDesktop) -> None: + contact = client.matrix.bridges.contacts.list( + bridge_id="bridgeID", + ) + assert_matches_type(ContactListResponse, contact, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: BeeperDesktop) -> None: + contact = client.matrix.bridges.contacts.list( + bridge_id="bridgeID", + login_id="bcc68892-b180-414f-9516-b4aadf7d0496", + ) + assert_matches_type(ContactListResponse, contact, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: BeeperDesktop) -> None: + response = client.matrix.bridges.contacts.with_raw_response.list( + bridge_id="bridgeID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + contact = response.parse() + assert_matches_type(ContactListResponse, contact, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: BeeperDesktop) -> None: + with client.matrix.bridges.contacts.with_streaming_response.list( + bridge_id="bridgeID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + contact = response.parse() + assert_matches_type(ContactListResponse, contact, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + client.matrix.bridges.contacts.with_raw_response.list( + bridge_id="", + ) + + +class TestAsyncContacts: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_list(self, async_client: AsyncBeeperDesktop) -> None: + contact = await async_client.matrix.bridges.contacts.list( + bridge_id="bridgeID", + ) + assert_matches_type(ContactListResponse, contact, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncBeeperDesktop) -> None: + contact = await async_client.matrix.bridges.contacts.list( + bridge_id="bridgeID", + login_id="bcc68892-b180-414f-9516-b4aadf7d0496", + ) + assert_matches_type(ContactListResponse, contact, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.bridges.contacts.with_raw_response.list( + bridge_id="bridgeID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + contact = await response.parse() + assert_matches_type(ContactListResponse, contact, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.bridges.contacts.with_streaming_response.list( + bridge_id="bridgeID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + contact = await response.parse() + assert_matches_type(ContactListResponse, contact, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + await async_client.matrix.bridges.contacts.with_raw_response.list( + bridge_id="", + ) diff --git a/tests/api_resources/matrix/bridges/test_rooms.py b/tests/api_resources/matrix/bridges/test_rooms.py new file mode 100644 index 0000000..d637533 --- /dev/null +++ b/tests/api_resources/matrix/bridges/test_rooms.py @@ -0,0 +1,279 @@ +# 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 tests.utils import assert_matches_type +from beeper_desktop_api import BeeperDesktop, AsyncBeeperDesktop +from beeper_desktop_api.types.matrix.bridges import ( + RoomCreateDmResponse, + RoomCreateGroupResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestRooms: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create_dm(self, client: BeeperDesktop) -> None: + room = client.matrix.bridges.rooms.create_dm( + identifier="identifier", + bridge_id="bridgeID", + ) + assert_matches_type(RoomCreateDmResponse, room, path=["response"]) + + @parametrize + def test_method_create_dm_with_all_params(self, client: BeeperDesktop) -> None: + room = client.matrix.bridges.rooms.create_dm( + identifier="identifier", + bridge_id="bridgeID", + login_id="bcc68892-b180-414f-9516-b4aadf7d0496", + ) + assert_matches_type(RoomCreateDmResponse, room, path=["response"]) + + @parametrize + def test_raw_response_create_dm(self, client: BeeperDesktop) -> None: + response = client.matrix.bridges.rooms.with_raw_response.create_dm( + identifier="identifier", + bridge_id="bridgeID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + room = response.parse() + assert_matches_type(RoomCreateDmResponse, room, path=["response"]) + + @parametrize + def test_streaming_response_create_dm(self, client: BeeperDesktop) -> None: + with client.matrix.bridges.rooms.with_streaming_response.create_dm( + identifier="identifier", + bridge_id="bridgeID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + room = response.parse() + assert_matches_type(RoomCreateDmResponse, room, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create_dm(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + client.matrix.bridges.rooms.with_raw_response.create_dm( + identifier="identifier", + bridge_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `identifier` but received ''"): + client.matrix.bridges.rooms.with_raw_response.create_dm( + identifier="", + bridge_id="bridgeID", + ) + + @parametrize + def test_method_create_group(self, client: BeeperDesktop) -> None: + room = client.matrix.bridges.rooms.create_group( + group_type="groupType", + bridge_id="bridgeID", + ) + assert_matches_type(RoomCreateGroupResponse, room, path=["response"]) + + @parametrize + def test_method_create_group_with_all_params(self, client: BeeperDesktop) -> None: + room = client.matrix.bridges.rooms.create_group( + group_type="groupType", + bridge_id="bridgeID", + login_id="bcc68892-b180-414f-9516-b4aadf7d0496", + avatar={"url": "url"}, + disappear={ + "timer": 0, + "type": "type", + }, + name={"name": "name"}, + parent={}, + participants=["string"], + room_id="room_id", + topic={"topic": "topic"}, + type="channel", + username="username", + ) + assert_matches_type(RoomCreateGroupResponse, room, path=["response"]) + + @parametrize + def test_raw_response_create_group(self, client: BeeperDesktop) -> None: + response = client.matrix.bridges.rooms.with_raw_response.create_group( + group_type="groupType", + bridge_id="bridgeID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + room = response.parse() + assert_matches_type(RoomCreateGroupResponse, room, path=["response"]) + + @parametrize + def test_streaming_response_create_group(self, client: BeeperDesktop) -> None: + with client.matrix.bridges.rooms.with_streaming_response.create_group( + group_type="groupType", + bridge_id="bridgeID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + room = response.parse() + assert_matches_type(RoomCreateGroupResponse, room, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create_group(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + client.matrix.bridges.rooms.with_raw_response.create_group( + group_type="groupType", + bridge_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `group_type` but received ''"): + client.matrix.bridges.rooms.with_raw_response.create_group( + group_type="", + bridge_id="bridgeID", + ) + + +class TestAsyncRooms: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create_dm(self, async_client: AsyncBeeperDesktop) -> None: + room = await async_client.matrix.bridges.rooms.create_dm( + identifier="identifier", + bridge_id="bridgeID", + ) + assert_matches_type(RoomCreateDmResponse, room, path=["response"]) + + @parametrize + async def test_method_create_dm_with_all_params(self, async_client: AsyncBeeperDesktop) -> None: + room = await async_client.matrix.bridges.rooms.create_dm( + identifier="identifier", + bridge_id="bridgeID", + login_id="bcc68892-b180-414f-9516-b4aadf7d0496", + ) + assert_matches_type(RoomCreateDmResponse, room, path=["response"]) + + @parametrize + async def test_raw_response_create_dm(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.bridges.rooms.with_raw_response.create_dm( + identifier="identifier", + bridge_id="bridgeID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + room = await response.parse() + assert_matches_type(RoomCreateDmResponse, room, path=["response"]) + + @parametrize + async def test_streaming_response_create_dm(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.bridges.rooms.with_streaming_response.create_dm( + identifier="identifier", + bridge_id="bridgeID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + room = await response.parse() + assert_matches_type(RoomCreateDmResponse, room, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create_dm(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + await async_client.matrix.bridges.rooms.with_raw_response.create_dm( + identifier="identifier", + bridge_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `identifier` but received ''"): + await async_client.matrix.bridges.rooms.with_raw_response.create_dm( + identifier="", + bridge_id="bridgeID", + ) + + @parametrize + async def test_method_create_group(self, async_client: AsyncBeeperDesktop) -> None: + room = await async_client.matrix.bridges.rooms.create_group( + group_type="groupType", + bridge_id="bridgeID", + ) + assert_matches_type(RoomCreateGroupResponse, room, path=["response"]) + + @parametrize + async def test_method_create_group_with_all_params(self, async_client: AsyncBeeperDesktop) -> None: + room = await async_client.matrix.bridges.rooms.create_group( + group_type="groupType", + bridge_id="bridgeID", + login_id="bcc68892-b180-414f-9516-b4aadf7d0496", + avatar={"url": "url"}, + disappear={ + "timer": 0, + "type": "type", + }, + name={"name": "name"}, + parent={}, + participants=["string"], + room_id="room_id", + topic={"topic": "topic"}, + type="channel", + username="username", + ) + assert_matches_type(RoomCreateGroupResponse, room, path=["response"]) + + @parametrize + async def test_raw_response_create_group(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.bridges.rooms.with_raw_response.create_group( + group_type="groupType", + bridge_id="bridgeID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + room = await response.parse() + assert_matches_type(RoomCreateGroupResponse, room, path=["response"]) + + @parametrize + async def test_streaming_response_create_group(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.bridges.rooms.with_streaming_response.create_group( + group_type="groupType", + bridge_id="bridgeID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + room = await response.parse() + assert_matches_type(RoomCreateGroupResponse, room, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create_group(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + await async_client.matrix.bridges.rooms.with_raw_response.create_group( + group_type="groupType", + bridge_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `group_type` but received ''"): + await async_client.matrix.bridges.rooms.with_raw_response.create_group( + group_type="", + bridge_id="bridgeID", + ) diff --git a/tests/api_resources/matrix/bridges/test_users.py b/tests/api_resources/matrix/bridges/test_users.py new file mode 100644 index 0000000..2e6e69d --- /dev/null +++ b/tests/api_resources/matrix/bridges/test_users.py @@ -0,0 +1,235 @@ +# 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 tests.utils import assert_matches_type +from beeper_desktop_api import BeeperDesktop, AsyncBeeperDesktop +from beeper_desktop_api.types.matrix.bridges import ( + UserSearchResponse, + UserResolveResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestUsers: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_resolve(self, client: BeeperDesktop) -> None: + user = client.matrix.bridges.users.resolve( + identifier="identifier", + bridge_id="bridgeID", + ) + assert_matches_type(UserResolveResponse, user, path=["response"]) + + @parametrize + def test_method_resolve_with_all_params(self, client: BeeperDesktop) -> None: + user = client.matrix.bridges.users.resolve( + identifier="identifier", + bridge_id="bridgeID", + login_id="bcc68892-b180-414f-9516-b4aadf7d0496", + ) + assert_matches_type(UserResolveResponse, user, path=["response"]) + + @parametrize + def test_raw_response_resolve(self, client: BeeperDesktop) -> None: + response = client.matrix.bridges.users.with_raw_response.resolve( + identifier="identifier", + bridge_id="bridgeID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = response.parse() + assert_matches_type(UserResolveResponse, user, path=["response"]) + + @parametrize + def test_streaming_response_resolve(self, client: BeeperDesktop) -> None: + with client.matrix.bridges.users.with_streaming_response.resolve( + identifier="identifier", + bridge_id="bridgeID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = response.parse() + assert_matches_type(UserResolveResponse, user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_resolve(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + client.matrix.bridges.users.with_raw_response.resolve( + identifier="identifier", + bridge_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `identifier` but received ''"): + client.matrix.bridges.users.with_raw_response.resolve( + identifier="", + bridge_id="bridgeID", + ) + + @parametrize + def test_method_search(self, client: BeeperDesktop) -> None: + user = client.matrix.bridges.users.search( + bridge_id="bridgeID", + ) + assert_matches_type(UserSearchResponse, user, path=["response"]) + + @parametrize + def test_method_search_with_all_params(self, client: BeeperDesktop) -> None: + user = client.matrix.bridges.users.search( + bridge_id="bridgeID", + login_id="bcc68892-b180-414f-9516-b4aadf7d0496", + query="query", + ) + assert_matches_type(UserSearchResponse, user, path=["response"]) + + @parametrize + def test_raw_response_search(self, client: BeeperDesktop) -> None: + response = client.matrix.bridges.users.with_raw_response.search( + bridge_id="bridgeID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = response.parse() + assert_matches_type(UserSearchResponse, user, path=["response"]) + + @parametrize + def test_streaming_response_search(self, client: BeeperDesktop) -> None: + with client.matrix.bridges.users.with_streaming_response.search( + bridge_id="bridgeID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = response.parse() + assert_matches_type(UserSearchResponse, user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_search(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + client.matrix.bridges.users.with_raw_response.search( + bridge_id="", + ) + + +class TestAsyncUsers: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_resolve(self, async_client: AsyncBeeperDesktop) -> None: + user = await async_client.matrix.bridges.users.resolve( + identifier="identifier", + bridge_id="bridgeID", + ) + assert_matches_type(UserResolveResponse, user, path=["response"]) + + @parametrize + async def test_method_resolve_with_all_params(self, async_client: AsyncBeeperDesktop) -> None: + user = await async_client.matrix.bridges.users.resolve( + identifier="identifier", + bridge_id="bridgeID", + login_id="bcc68892-b180-414f-9516-b4aadf7d0496", + ) + assert_matches_type(UserResolveResponse, user, path=["response"]) + + @parametrize + async def test_raw_response_resolve(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.bridges.users.with_raw_response.resolve( + identifier="identifier", + bridge_id="bridgeID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = await response.parse() + assert_matches_type(UserResolveResponse, user, path=["response"]) + + @parametrize + async def test_streaming_response_resolve(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.bridges.users.with_streaming_response.resolve( + identifier="identifier", + bridge_id="bridgeID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = await response.parse() + assert_matches_type(UserResolveResponse, user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_resolve(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + await async_client.matrix.bridges.users.with_raw_response.resolve( + identifier="identifier", + bridge_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `identifier` but received ''"): + await async_client.matrix.bridges.users.with_raw_response.resolve( + identifier="", + bridge_id="bridgeID", + ) + + @parametrize + async def test_method_search(self, async_client: AsyncBeeperDesktop) -> None: + user = await async_client.matrix.bridges.users.search( + bridge_id="bridgeID", + ) + assert_matches_type(UserSearchResponse, user, path=["response"]) + + @parametrize + async def test_method_search_with_all_params(self, async_client: AsyncBeeperDesktop) -> None: + user = await async_client.matrix.bridges.users.search( + bridge_id="bridgeID", + login_id="bcc68892-b180-414f-9516-b4aadf7d0496", + query="query", + ) + assert_matches_type(UserSearchResponse, user, path=["response"]) + + @parametrize + async def test_raw_response_search(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.bridges.users.with_raw_response.search( + bridge_id="bridgeID", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = await response.parse() + assert_matches_type(UserSearchResponse, user, path=["response"]) + + @parametrize + async def test_streaming_response_search(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.bridges.users.with_streaming_response.search( + bridge_id="bridgeID", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = await response.parse() + assert_matches_type(UserSearchResponse, user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_search(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bridge_id` but received ''"): + await async_client.matrix.bridges.users.with_raw_response.search( + bridge_id="", + ) diff --git a/tests/api_resources/matrix/rooms/__init__.py b/tests/api_resources/matrix/rooms/__init__.py new file mode 100644 index 0000000..fd8019a --- /dev/null +++ b/tests/api_resources/matrix/rooms/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/matrix/rooms/test_account_data.py b/tests/api_resources/matrix/rooms/test_account_data.py new file mode 100644 index 0000000..913996c --- /dev/null +++ b/tests/api_resources/matrix/rooms/test_account_data.py @@ -0,0 +1,275 @@ +# 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 tests.utils import assert_matches_type +from beeper_desktop_api import BeeperDesktop, AsyncBeeperDesktop + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestAccountData: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_retrieve(self, client: BeeperDesktop) -> None: + account_data = client.matrix.rooms.account_data.retrieve( + type="org.example.custom.room.config", + user_id="@alice:example.com", + room_id="!726s6s6q:example.com", + ) + assert_matches_type(object, account_data, path=["response"]) + + @parametrize + def test_raw_response_retrieve(self, client: BeeperDesktop) -> None: + response = client.matrix.rooms.account_data.with_raw_response.retrieve( + type="org.example.custom.room.config", + user_id="@alice:example.com", + room_id="!726s6s6q:example.com", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + account_data = response.parse() + assert_matches_type(object, account_data, path=["response"]) + + @parametrize + def test_streaming_response_retrieve(self, client: BeeperDesktop) -> None: + with client.matrix.rooms.account_data.with_streaming_response.retrieve( + type="org.example.custom.room.config", + user_id="@alice:example.com", + room_id="!726s6s6q:example.com", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + account_data = response.parse() + assert_matches_type(object, account_data, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_retrieve(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + client.matrix.rooms.account_data.with_raw_response.retrieve( + type="org.example.custom.room.config", + user_id="", + room_id="!726s6s6q:example.com", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `room_id` but received ''"): + client.matrix.rooms.account_data.with_raw_response.retrieve( + type="org.example.custom.room.config", + user_id="@alice:example.com", + room_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `type` but received ''"): + client.matrix.rooms.account_data.with_raw_response.retrieve( + type="", + user_id="@alice:example.com", + room_id="!726s6s6q:example.com", + ) + + @parametrize + def test_method_update(self, client: BeeperDesktop) -> None: + account_data = client.matrix.rooms.account_data.update( + type="org.example.custom.room.config", + user_id="@alice:example.com", + room_id="!726s6s6q:example.com", + body={"custom_account_data_key": "custom_account_data_value"}, + ) + assert_matches_type(object, account_data, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: BeeperDesktop) -> None: + response = client.matrix.rooms.account_data.with_raw_response.update( + type="org.example.custom.room.config", + user_id="@alice:example.com", + room_id="!726s6s6q:example.com", + body={"custom_account_data_key": "custom_account_data_value"}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + account_data = response.parse() + assert_matches_type(object, account_data, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: BeeperDesktop) -> None: + with client.matrix.rooms.account_data.with_streaming_response.update( + type="org.example.custom.room.config", + user_id="@alice:example.com", + room_id="!726s6s6q:example.com", + body={"custom_account_data_key": "custom_account_data_value"}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + account_data = response.parse() + assert_matches_type(object, account_data, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + client.matrix.rooms.account_data.with_raw_response.update( + type="org.example.custom.room.config", + user_id="", + room_id="!726s6s6q:example.com", + body={"custom_account_data_key": "custom_account_data_value"}, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `room_id` but received ''"): + client.matrix.rooms.account_data.with_raw_response.update( + type="org.example.custom.room.config", + user_id="@alice:example.com", + room_id="", + body={"custom_account_data_key": "custom_account_data_value"}, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `type` but received ''"): + client.matrix.rooms.account_data.with_raw_response.update( + type="", + user_id="@alice:example.com", + room_id="!726s6s6q:example.com", + body={"custom_account_data_key": "custom_account_data_value"}, + ) + + +class TestAsyncAccountData: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_retrieve(self, async_client: AsyncBeeperDesktop) -> None: + account_data = await async_client.matrix.rooms.account_data.retrieve( + type="org.example.custom.room.config", + user_id="@alice:example.com", + room_id="!726s6s6q:example.com", + ) + assert_matches_type(object, account_data, path=["response"]) + + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.rooms.account_data.with_raw_response.retrieve( + type="org.example.custom.room.config", + user_id="@alice:example.com", + room_id="!726s6s6q:example.com", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + account_data = await response.parse() + assert_matches_type(object, account_data, path=["response"]) + + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.rooms.account_data.with_streaming_response.retrieve( + type="org.example.custom.room.config", + user_id="@alice:example.com", + room_id="!726s6s6q:example.com", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + account_data = await response.parse() + assert_matches_type(object, account_data, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + await async_client.matrix.rooms.account_data.with_raw_response.retrieve( + type="org.example.custom.room.config", + user_id="", + room_id="!726s6s6q:example.com", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `room_id` but received ''"): + await async_client.matrix.rooms.account_data.with_raw_response.retrieve( + type="org.example.custom.room.config", + user_id="@alice:example.com", + room_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `type` but received ''"): + await async_client.matrix.rooms.account_data.with_raw_response.retrieve( + type="", + user_id="@alice:example.com", + room_id="!726s6s6q:example.com", + ) + + @parametrize + async def test_method_update(self, async_client: AsyncBeeperDesktop) -> None: + account_data = await async_client.matrix.rooms.account_data.update( + type="org.example.custom.room.config", + user_id="@alice:example.com", + room_id="!726s6s6q:example.com", + body={"custom_account_data_key": "custom_account_data_value"}, + ) + assert_matches_type(object, account_data, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.rooms.account_data.with_raw_response.update( + type="org.example.custom.room.config", + user_id="@alice:example.com", + room_id="!726s6s6q:example.com", + body={"custom_account_data_key": "custom_account_data_value"}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + account_data = await response.parse() + assert_matches_type(object, account_data, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.rooms.account_data.with_streaming_response.update( + type="org.example.custom.room.config", + user_id="@alice:example.com", + room_id="!726s6s6q:example.com", + body={"custom_account_data_key": "custom_account_data_value"}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + account_data = await response.parse() + assert_matches_type(object, account_data, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + await async_client.matrix.rooms.account_data.with_raw_response.update( + type="org.example.custom.room.config", + user_id="", + room_id="!726s6s6q:example.com", + body={"custom_account_data_key": "custom_account_data_value"}, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `room_id` but received ''"): + await async_client.matrix.rooms.account_data.with_raw_response.update( + type="org.example.custom.room.config", + user_id="@alice:example.com", + room_id="", + body={"custom_account_data_key": "custom_account_data_value"}, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `type` but received ''"): + await async_client.matrix.rooms.account_data.with_raw_response.update( + type="", + user_id="@alice:example.com", + room_id="!726s6s6q:example.com", + body={"custom_account_data_key": "custom_account_data_value"}, + ) diff --git a/tests/api_resources/matrix/rooms/test_events.py b/tests/api_resources/matrix/rooms/test_events.py new file mode 100644 index 0000000..4610a72 --- /dev/null +++ b/tests/api_resources/matrix/rooms/test_events.py @@ -0,0 +1,120 @@ +# 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 tests.utils import assert_matches_type +from beeper_desktop_api import BeeperDesktop, AsyncBeeperDesktop +from beeper_desktop_api.types.matrix.rooms import EventRetrieveResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestEvents: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_retrieve(self, client: BeeperDesktop) -> None: + event = client.matrix.rooms.events.retrieve( + event_id="$asfDuShaf7Gafaw:matrix.org", + room_id="!636q39766251:matrix.org", + ) + assert_matches_type(EventRetrieveResponse, event, path=["response"]) + + @parametrize + def test_raw_response_retrieve(self, client: BeeperDesktop) -> None: + response = client.matrix.rooms.events.with_raw_response.retrieve( + event_id="$asfDuShaf7Gafaw:matrix.org", + room_id="!636q39766251:matrix.org", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + event = response.parse() + assert_matches_type(EventRetrieveResponse, event, path=["response"]) + + @parametrize + def test_streaming_response_retrieve(self, client: BeeperDesktop) -> None: + with client.matrix.rooms.events.with_streaming_response.retrieve( + event_id="$asfDuShaf7Gafaw:matrix.org", + room_id="!636q39766251:matrix.org", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + event = response.parse() + assert_matches_type(EventRetrieveResponse, event, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_retrieve(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `room_id` but received ''"): + client.matrix.rooms.events.with_raw_response.retrieve( + event_id="$asfDuShaf7Gafaw:matrix.org", + room_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `event_id` but received ''"): + client.matrix.rooms.events.with_raw_response.retrieve( + event_id="", + room_id="!636q39766251:matrix.org", + ) + + +class TestAsyncEvents: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_retrieve(self, async_client: AsyncBeeperDesktop) -> None: + event = await async_client.matrix.rooms.events.retrieve( + event_id="$asfDuShaf7Gafaw:matrix.org", + room_id="!636q39766251:matrix.org", + ) + assert_matches_type(EventRetrieveResponse, event, path=["response"]) + + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.rooms.events.with_raw_response.retrieve( + event_id="$asfDuShaf7Gafaw:matrix.org", + room_id="!636q39766251:matrix.org", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + event = await response.parse() + assert_matches_type(EventRetrieveResponse, event, path=["response"]) + + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.rooms.events.with_streaming_response.retrieve( + event_id="$asfDuShaf7Gafaw:matrix.org", + room_id="!636q39766251:matrix.org", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + event = await response.parse() + assert_matches_type(EventRetrieveResponse, event, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `room_id` but received ''"): + await async_client.matrix.rooms.events.with_raw_response.retrieve( + event_id="$asfDuShaf7Gafaw:matrix.org", + room_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `event_id` but received ''"): + await async_client.matrix.rooms.events.with_raw_response.retrieve( + event_id="", + room_id="!636q39766251:matrix.org", + ) diff --git a/tests/api_resources/matrix/rooms/test_state.py b/tests/api_resources/matrix/rooms/test_state.py new file mode 100644 index 0000000..8749cff --- /dev/null +++ b/tests/api_resources/matrix/rooms/test_state.py @@ -0,0 +1,240 @@ +# 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 tests.utils import assert_matches_type +from beeper_desktop_api import BeeperDesktop, AsyncBeeperDesktop +from beeper_desktop_api.types.matrix.rooms import StateListResponse, StateRetrieveResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestState: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_retrieve(self, client: BeeperDesktop) -> None: + state = client.matrix.rooms.state.retrieve( + state_key="state_key", + room_id="!636q39766251:example.com", + event_type="m.room.name", + ) + assert_matches_type(StateRetrieveResponse, state, path=["response"]) + + @parametrize + def test_method_retrieve_with_all_params(self, client: BeeperDesktop) -> None: + state = client.matrix.rooms.state.retrieve( + state_key="state_key", + room_id="!636q39766251:example.com", + event_type="m.room.name", + format="content", + ) + assert_matches_type(StateRetrieveResponse, state, path=["response"]) + + @parametrize + def test_raw_response_retrieve(self, client: BeeperDesktop) -> None: + response = client.matrix.rooms.state.with_raw_response.retrieve( + state_key="state_key", + room_id="!636q39766251:example.com", + event_type="m.room.name", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + state = response.parse() + assert_matches_type(StateRetrieveResponse, state, path=["response"]) + + @parametrize + def test_streaming_response_retrieve(self, client: BeeperDesktop) -> None: + with client.matrix.rooms.state.with_streaming_response.retrieve( + state_key="state_key", + room_id="!636q39766251:example.com", + event_type="m.room.name", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + state = response.parse() + assert_matches_type(StateRetrieveResponse, state, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_retrieve(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `room_id` but received ''"): + client.matrix.rooms.state.with_raw_response.retrieve( + state_key="state_key", + room_id="", + event_type="m.room.name", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `event_type` but received ''"): + client.matrix.rooms.state.with_raw_response.retrieve( + state_key="state_key", + room_id="!636q39766251:example.com", + event_type="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `state_key` but received ''"): + client.matrix.rooms.state.with_raw_response.retrieve( + state_key="", + room_id="!636q39766251:example.com", + event_type="m.room.name", + ) + + @parametrize + def test_method_list(self, client: BeeperDesktop) -> None: + state = client.matrix.rooms.state.list( + "!636q39766251:example.com", + ) + assert_matches_type(StateListResponse, state, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: BeeperDesktop) -> None: + response = client.matrix.rooms.state.with_raw_response.list( + "!636q39766251:example.com", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + state = response.parse() + assert_matches_type(StateListResponse, state, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: BeeperDesktop) -> None: + with client.matrix.rooms.state.with_streaming_response.list( + "!636q39766251:example.com", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + state = response.parse() + assert_matches_type(StateListResponse, state, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `room_id` but received ''"): + client.matrix.rooms.state.with_raw_response.list( + "", + ) + + +class TestAsyncState: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_retrieve(self, async_client: AsyncBeeperDesktop) -> None: + state = await async_client.matrix.rooms.state.retrieve( + state_key="state_key", + room_id="!636q39766251:example.com", + event_type="m.room.name", + ) + assert_matches_type(StateRetrieveResponse, state, path=["response"]) + + @parametrize + async def test_method_retrieve_with_all_params(self, async_client: AsyncBeeperDesktop) -> None: + state = await async_client.matrix.rooms.state.retrieve( + state_key="state_key", + room_id="!636q39766251:example.com", + event_type="m.room.name", + format="content", + ) + assert_matches_type(StateRetrieveResponse, state, path=["response"]) + + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.rooms.state.with_raw_response.retrieve( + state_key="state_key", + room_id="!636q39766251:example.com", + event_type="m.room.name", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + state = await response.parse() + assert_matches_type(StateRetrieveResponse, state, path=["response"]) + + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.rooms.state.with_streaming_response.retrieve( + state_key="state_key", + room_id="!636q39766251:example.com", + event_type="m.room.name", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + state = await response.parse() + assert_matches_type(StateRetrieveResponse, state, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `room_id` but received ''"): + await async_client.matrix.rooms.state.with_raw_response.retrieve( + state_key="state_key", + room_id="", + event_type="m.room.name", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `event_type` but received ''"): + await async_client.matrix.rooms.state.with_raw_response.retrieve( + state_key="state_key", + room_id="!636q39766251:example.com", + event_type="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `state_key` but received ''"): + await async_client.matrix.rooms.state.with_raw_response.retrieve( + state_key="", + room_id="!636q39766251:example.com", + event_type="m.room.name", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncBeeperDesktop) -> None: + state = await async_client.matrix.rooms.state.list( + "!636q39766251:example.com", + ) + assert_matches_type(StateListResponse, state, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.rooms.state.with_raw_response.list( + "!636q39766251:example.com", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + state = await response.parse() + assert_matches_type(StateListResponse, state, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.rooms.state.with_streaming_response.list( + "!636q39766251:example.com", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + state = await response.parse() + assert_matches_type(StateListResponse, state, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `room_id` but received ''"): + await async_client.matrix.rooms.state.with_raw_response.list( + "", + ) diff --git a/tests/api_resources/matrix/test_rooms.py b/tests/api_resources/matrix/test_rooms.py new file mode 100644 index 0000000..6c9f5a1 --- /dev/null +++ b/tests/api_resources/matrix/test_rooms.py @@ -0,0 +1,337 @@ +# 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 tests.utils import assert_matches_type +from beeper_desktop_api import BeeperDesktop, AsyncBeeperDesktop +from beeper_desktop_api.types.matrix import ( + RoomJoinResponse, + RoomCreateResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestRooms: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: BeeperDesktop) -> None: + room = client.matrix.rooms.create() + assert_matches_type(RoomCreateResponse, room, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: BeeperDesktop) -> None: + room = client.matrix.rooms.create( + creation_content={"m.federate": False}, + initial_state=[ + { + "content": {}, + "type": "type", + "state_key": "state_key", + } + ], + invite=["string"], + invite_3pid=[ + { + "address": "cheeky@monkey.com", + "id_access_token": "abc123_OpaqueString", + "id_server": "matrix.org", + "medium": "email", + } + ], + is_direct=True, + name="The Grand Duke Pub", + power_level_content_override={}, + preset="public_chat", + room_alias_name="thepub", + room_version="1", + topic="All about happy hour", + visibility="public", + ) + assert_matches_type(RoomCreateResponse, room, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: BeeperDesktop) -> None: + response = client.matrix.rooms.with_raw_response.create() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + room = response.parse() + assert_matches_type(RoomCreateResponse, room, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: BeeperDesktop) -> None: + with client.matrix.rooms.with_streaming_response.create() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + room = response.parse() + assert_matches_type(RoomCreateResponse, room, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_method_join(self, client: BeeperDesktop) -> None: + room = client.matrix.rooms.join( + room_id_or_alias="!monkeys:matrix.org", + ) + assert_matches_type(RoomJoinResponse, room, path=["response"]) + + @parametrize + def test_method_join_with_all_params(self, client: BeeperDesktop) -> None: + room = client.matrix.rooms.join( + room_id_or_alias="!monkeys:matrix.org", + via=["string"], + reason="Looking for support", + third_party_signed={ + "token": "random8nonce", + "mxid": "bob", + "sender": "alice", + "signatures": {"example.org": {"ed25519:0": "some9signature"}}, + }, + ) + assert_matches_type(RoomJoinResponse, room, path=["response"]) + + @parametrize + def test_raw_response_join(self, client: BeeperDesktop) -> None: + response = client.matrix.rooms.with_raw_response.join( + room_id_or_alias="!monkeys:matrix.org", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + room = response.parse() + assert_matches_type(RoomJoinResponse, room, path=["response"]) + + @parametrize + def test_streaming_response_join(self, client: BeeperDesktop) -> None: + with client.matrix.rooms.with_streaming_response.join( + room_id_or_alias="!monkeys:matrix.org", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + room = response.parse() + assert_matches_type(RoomJoinResponse, room, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_join(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `room_id_or_alias` but received ''"): + client.matrix.rooms.with_raw_response.join( + room_id_or_alias="", + ) + + @parametrize + def test_method_leave(self, client: BeeperDesktop) -> None: + room = client.matrix.rooms.leave( + room_id="!nkl290a:matrix.org", + ) + assert_matches_type(object, room, path=["response"]) + + @parametrize + def test_method_leave_with_all_params(self, client: BeeperDesktop) -> None: + room = client.matrix.rooms.leave( + room_id="!nkl290a:matrix.org", + reason="Saying farewell - thanks for the support!", + ) + assert_matches_type(object, room, path=["response"]) + + @parametrize + def test_raw_response_leave(self, client: BeeperDesktop) -> None: + response = client.matrix.rooms.with_raw_response.leave( + room_id="!nkl290a:matrix.org", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + room = response.parse() + assert_matches_type(object, room, path=["response"]) + + @parametrize + def test_streaming_response_leave(self, client: BeeperDesktop) -> None: + with client.matrix.rooms.with_streaming_response.leave( + room_id="!nkl290a:matrix.org", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + room = response.parse() + assert_matches_type(object, room, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_leave(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `room_id` but received ''"): + client.matrix.rooms.with_raw_response.leave( + room_id="", + ) + + +class TestAsyncRooms: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create(self, async_client: AsyncBeeperDesktop) -> None: + room = await async_client.matrix.rooms.create() + assert_matches_type(RoomCreateResponse, room, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncBeeperDesktop) -> None: + room = await async_client.matrix.rooms.create( + creation_content={"m.federate": False}, + initial_state=[ + { + "content": {}, + "type": "type", + "state_key": "state_key", + } + ], + invite=["string"], + invite_3pid=[ + { + "address": "cheeky@monkey.com", + "id_access_token": "abc123_OpaqueString", + "id_server": "matrix.org", + "medium": "email", + } + ], + is_direct=True, + name="The Grand Duke Pub", + power_level_content_override={}, + preset="public_chat", + room_alias_name="thepub", + room_version="1", + topic="All about happy hour", + visibility="public", + ) + assert_matches_type(RoomCreateResponse, room, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.rooms.with_raw_response.create() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + room = await response.parse() + assert_matches_type(RoomCreateResponse, room, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.rooms.with_streaming_response.create() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + room = await response.parse() + assert_matches_type(RoomCreateResponse, room, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_method_join(self, async_client: AsyncBeeperDesktop) -> None: + room = await async_client.matrix.rooms.join( + room_id_or_alias="!monkeys:matrix.org", + ) + assert_matches_type(RoomJoinResponse, room, path=["response"]) + + @parametrize + async def test_method_join_with_all_params(self, async_client: AsyncBeeperDesktop) -> None: + room = await async_client.matrix.rooms.join( + room_id_or_alias="!monkeys:matrix.org", + via=["string"], + reason="Looking for support", + third_party_signed={ + "token": "random8nonce", + "mxid": "bob", + "sender": "alice", + "signatures": {"example.org": {"ed25519:0": "some9signature"}}, + }, + ) + assert_matches_type(RoomJoinResponse, room, path=["response"]) + + @parametrize + async def test_raw_response_join(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.rooms.with_raw_response.join( + room_id_or_alias="!monkeys:matrix.org", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + room = await response.parse() + assert_matches_type(RoomJoinResponse, room, path=["response"]) + + @parametrize + async def test_streaming_response_join(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.rooms.with_streaming_response.join( + room_id_or_alias="!monkeys:matrix.org", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + room = await response.parse() + assert_matches_type(RoomJoinResponse, room, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_join(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `room_id_or_alias` but received ''"): + await async_client.matrix.rooms.with_raw_response.join( + room_id_or_alias="", + ) + + @parametrize + async def test_method_leave(self, async_client: AsyncBeeperDesktop) -> None: + room = await async_client.matrix.rooms.leave( + room_id="!nkl290a:matrix.org", + ) + assert_matches_type(object, room, path=["response"]) + + @parametrize + async def test_method_leave_with_all_params(self, async_client: AsyncBeeperDesktop) -> None: + room = await async_client.matrix.rooms.leave( + room_id="!nkl290a:matrix.org", + reason="Saying farewell - thanks for the support!", + ) + assert_matches_type(object, room, path=["response"]) + + @parametrize + async def test_raw_response_leave(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.rooms.with_raw_response.leave( + room_id="!nkl290a:matrix.org", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + room = await response.parse() + assert_matches_type(object, room, path=["response"]) + + @parametrize + async def test_streaming_response_leave(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.rooms.with_streaming_response.leave( + room_id="!nkl290a:matrix.org", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + room = await response.parse() + assert_matches_type(object, room, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_leave(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `room_id` but received ''"): + await async_client.matrix.rooms.with_raw_response.leave( + room_id="", + ) diff --git a/tests/api_resources/matrix/test_users.py b/tests/api_resources/matrix/test_users.py new file mode 100644 index 0000000..5b148a2 --- /dev/null +++ b/tests/api_resources/matrix/test_users.py @@ -0,0 +1,100 @@ +# 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 tests.utils import assert_matches_type +from beeper_desktop_api import BeeperDesktop, AsyncBeeperDesktop +from beeper_desktop_api.types.matrix import UserRetrieveProfileResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestUsers: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_retrieve_profile(self, client: BeeperDesktop) -> None: + user = client.matrix.users.retrieve_profile( + "@alice:example.com", + ) + assert_matches_type(UserRetrieveProfileResponse, user, path=["response"]) + + @parametrize + def test_raw_response_retrieve_profile(self, client: BeeperDesktop) -> None: + response = client.matrix.users.with_raw_response.retrieve_profile( + "@alice:example.com", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = response.parse() + assert_matches_type(UserRetrieveProfileResponse, user, path=["response"]) + + @parametrize + def test_streaming_response_retrieve_profile(self, client: BeeperDesktop) -> None: + with client.matrix.users.with_streaming_response.retrieve_profile( + "@alice:example.com", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = response.parse() + assert_matches_type(UserRetrieveProfileResponse, user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_retrieve_profile(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + client.matrix.users.with_raw_response.retrieve_profile( + "", + ) + + +class TestAsyncUsers: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_retrieve_profile(self, async_client: AsyncBeeperDesktop) -> None: + user = await async_client.matrix.users.retrieve_profile( + "@alice:example.com", + ) + assert_matches_type(UserRetrieveProfileResponse, user, path=["response"]) + + @parametrize + async def test_raw_response_retrieve_profile(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.users.with_raw_response.retrieve_profile( + "@alice:example.com", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = await response.parse() + assert_matches_type(UserRetrieveProfileResponse, user, path=["response"]) + + @parametrize + async def test_streaming_response_retrieve_profile(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.users.with_streaming_response.retrieve_profile( + "@alice:example.com", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = await response.parse() + assert_matches_type(UserRetrieveProfileResponse, user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_retrieve_profile(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + await async_client.matrix.users.with_raw_response.retrieve_profile( + "", + ) diff --git a/tests/api_resources/matrix/users/__init__.py b/tests/api_resources/matrix/users/__init__.py new file mode 100644 index 0000000..fd8019a --- /dev/null +++ b/tests/api_resources/matrix/users/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/matrix/users/test_account_data.py b/tests/api_resources/matrix/users/test_account_data.py new file mode 100644 index 0000000..4e31b87 --- /dev/null +++ b/tests/api_resources/matrix/users/test_account_data.py @@ -0,0 +1,225 @@ +# 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 tests.utils import assert_matches_type +from beeper_desktop_api import BeeperDesktop, AsyncBeeperDesktop + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestAccountData: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_retrieve(self, client: BeeperDesktop) -> None: + account_data = client.matrix.users.account_data.retrieve( + type="org.example.custom.config", + user_id="@alice:example.com", + ) + assert_matches_type(object, account_data, path=["response"]) + + @parametrize + def test_raw_response_retrieve(self, client: BeeperDesktop) -> None: + response = client.matrix.users.account_data.with_raw_response.retrieve( + type="org.example.custom.config", + user_id="@alice:example.com", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + account_data = response.parse() + assert_matches_type(object, account_data, path=["response"]) + + @parametrize + def test_streaming_response_retrieve(self, client: BeeperDesktop) -> None: + with client.matrix.users.account_data.with_streaming_response.retrieve( + type="org.example.custom.config", + user_id="@alice:example.com", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + account_data = response.parse() + assert_matches_type(object, account_data, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_retrieve(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + client.matrix.users.account_data.with_raw_response.retrieve( + type="org.example.custom.config", + user_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `type` but received ''"): + client.matrix.users.account_data.with_raw_response.retrieve( + type="", + user_id="@alice:example.com", + ) + + @parametrize + def test_method_update(self, client: BeeperDesktop) -> None: + account_data = client.matrix.users.account_data.update( + type="org.example.custom.config", + user_id="@alice:example.com", + body={"custom_account_data_key": "custom_config_value"}, + ) + assert_matches_type(object, account_data, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: BeeperDesktop) -> None: + response = client.matrix.users.account_data.with_raw_response.update( + type="org.example.custom.config", + user_id="@alice:example.com", + body={"custom_account_data_key": "custom_config_value"}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + account_data = response.parse() + assert_matches_type(object, account_data, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: BeeperDesktop) -> None: + with client.matrix.users.account_data.with_streaming_response.update( + type="org.example.custom.config", + user_id="@alice:example.com", + body={"custom_account_data_key": "custom_config_value"}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + account_data = response.parse() + assert_matches_type(object, account_data, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: BeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + client.matrix.users.account_data.with_raw_response.update( + type="org.example.custom.config", + user_id="", + body={"custom_account_data_key": "custom_config_value"}, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `type` but received ''"): + client.matrix.users.account_data.with_raw_response.update( + type="", + user_id="@alice:example.com", + body={"custom_account_data_key": "custom_config_value"}, + ) + + +class TestAsyncAccountData: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_retrieve(self, async_client: AsyncBeeperDesktop) -> None: + account_data = await async_client.matrix.users.account_data.retrieve( + type="org.example.custom.config", + user_id="@alice:example.com", + ) + assert_matches_type(object, account_data, path=["response"]) + + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.users.account_data.with_raw_response.retrieve( + type="org.example.custom.config", + user_id="@alice:example.com", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + account_data = await response.parse() + assert_matches_type(object, account_data, path=["response"]) + + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.users.account_data.with_streaming_response.retrieve( + type="org.example.custom.config", + user_id="@alice:example.com", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + account_data = await response.parse() + assert_matches_type(object, account_data, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + await async_client.matrix.users.account_data.with_raw_response.retrieve( + type="org.example.custom.config", + user_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `type` but received ''"): + await async_client.matrix.users.account_data.with_raw_response.retrieve( + type="", + user_id="@alice:example.com", + ) + + @parametrize + async def test_method_update(self, async_client: AsyncBeeperDesktop) -> None: + account_data = await async_client.matrix.users.account_data.update( + type="org.example.custom.config", + user_id="@alice:example.com", + body={"custom_account_data_key": "custom_config_value"}, + ) + assert_matches_type(object, account_data, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.matrix.users.account_data.with_raw_response.update( + type="org.example.custom.config", + user_id="@alice:example.com", + body={"custom_account_data_key": "custom_config_value"}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + account_data = await response.parse() + assert_matches_type(object, account_data, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.matrix.users.account_data.with_streaming_response.update( + type="org.example.custom.config", + user_id="@alice:example.com", + body={"custom_account_data_key": "custom_config_value"}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + account_data = await response.parse() + assert_matches_type(object, account_data, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncBeeperDesktop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + await async_client.matrix.users.account_data.with_raw_response.update( + type="org.example.custom.config", + user_id="", + body={"custom_account_data_key": "custom_config_value"}, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `type` but received ''"): + await async_client.matrix.users.account_data.with_raw_response.update( + type="", + user_id="@alice:example.com", + body={"custom_account_data_key": "custom_config_value"}, + ) diff --git a/tests/api_resources/test_app.py b/tests/api_resources/test_app.py new file mode 100644 index 0000000..ff78bb6 --- /dev/null +++ b/tests/api_resources/test_app.py @@ -0,0 +1,74 @@ +# 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 tests.utils import assert_matches_type +from beeper_desktop_api import BeeperDesktop, AsyncBeeperDesktop +from beeper_desktop_api.types import AppStatusResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestApp: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_status(self, client: BeeperDesktop) -> None: + app = client.app.status() + assert_matches_type(AppStatusResponse, app, path=["response"]) + + @parametrize + def test_raw_response_status(self, client: BeeperDesktop) -> None: + response = client.app.with_raw_response.status() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + app = response.parse() + assert_matches_type(AppStatusResponse, app, path=["response"]) + + @parametrize + def test_streaming_response_status(self, client: BeeperDesktop) -> None: + with client.app.with_streaming_response.status() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + app = response.parse() + assert_matches_type(AppStatusResponse, app, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncApp: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_status(self, async_client: AsyncBeeperDesktop) -> None: + app = await async_client.app.status() + assert_matches_type(AppStatusResponse, app, path=["response"]) + + @parametrize + async def test_raw_response_status(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.app.with_raw_response.status() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + app = await response.parse() + assert_matches_type(AppStatusResponse, app, path=["response"]) + + @parametrize + async def test_streaming_response_status(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.app.with_streaming_response.status() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + app = await response.parse() + assert_matches_type(AppStatusResponse, app, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_bridges.py b/tests/api_resources/test_bridges.py new file mode 100644 index 0000000..f5af604 --- /dev/null +++ b/tests/api_resources/test_bridges.py @@ -0,0 +1,74 @@ +# 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 tests.utils import assert_matches_type +from beeper_desktop_api import BeeperDesktop, AsyncBeeperDesktop +from beeper_desktop_api.types import BridgeListResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestBridges: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_list(self, client: BeeperDesktop) -> None: + bridge = client.bridges.list() + assert_matches_type(BridgeListResponse, bridge, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: BeeperDesktop) -> None: + response = client.bridges.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + bridge = response.parse() + assert_matches_type(BridgeListResponse, bridge, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: BeeperDesktop) -> None: + with client.bridges.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + bridge = response.parse() + assert_matches_type(BridgeListResponse, bridge, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncBridges: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_list(self, async_client: AsyncBeeperDesktop) -> None: + bridge = await async_client.bridges.list() + assert_matches_type(BridgeListResponse, bridge, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncBeeperDesktop) -> None: + response = await async_client.bridges.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + bridge = await response.parse() + assert_matches_type(BridgeListResponse, bridge, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncBeeperDesktop) -> None: + async with async_client.bridges.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + bridge = await response.parse() + assert_matches_type(BridgeListResponse, bridge, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/test_models.py b/tests/test_models.py index e71da85..d228ea1 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -1,7 +1,8 @@ import json -from typing import TYPE_CHECKING, Any, Dict, List, Union, Optional, cast +from typing import TYPE_CHECKING, Any, Dict, List, Union, Iterable, Optional, cast from datetime import datetime, timezone -from typing_extensions import Literal, Annotated, TypeAliasType +from collections import deque +from typing_extensions import Literal, Annotated, TypedDict, TypeAliasType import pytest import pydantic @@ -9,7 +10,7 @@ from beeper_desktop_api._utils import PropertyInfo from beeper_desktop_api._compat import PYDANTIC_V1, parse_obj, model_dump, model_json -from beeper_desktop_api._models import DISCRIMINATOR_CACHE, BaseModel, construct_type +from beeper_desktop_api._models import DISCRIMINATOR_CACHE, BaseModel, EagerIterable, construct_type class BasicModel(BaseModel): @@ -961,3 +962,56 @@ def __getattr__(self, attr: str) -> Item: ... assert model.a.prop == 1 assert isinstance(model.a, Item) assert model.other == "foo" + + +# NOTE: Workaround for Pydantic Iterable behavior. +# Iterable fields are replaced with a ValidatorIterator and may be consumed +# during serialization, which can cause subsequent dumps to return empty data. +# See: https://github.com/pydantic/pydantic/issues/9541 +@pytest.mark.parametrize( + "data, expected_validated", + [ + ([1, 2, 3], [1, 2, 3]), + ((1, 2, 3), (1, 2, 3)), + (set([1, 2, 3]), set([1, 2, 3])), + (iter([1, 2, 3]), [1, 2, 3]), + ([], []), + ((x for x in [1, 2, 3]), [1, 2, 3]), + (map(lambda x: x, [1, 2, 3]), [1, 2, 3]), + (frozenset([1, 2, 3]), frozenset([1, 2, 3])), + (deque([1, 2, 3]), deque([1, 2, 3])), + ], + ids=["list", "tuple", "set", "iterator", "empty", "generator", "map", "frozenset", "deque"], +) +@pytest.mark.skipif(PYDANTIC_V1, reason="this is only supported in pydantic v2") +def test_iterable_construction(data: Iterable[int], expected_validated: Iterable[int]) -> None: + class TypeWithIterable(TypedDict): + items: EagerIterable[int] + + class Model(BaseModel): + data: TypeWithIterable + + m = Model.model_validate({"data": {"items": data}}) + assert m.data["items"] == expected_validated + + # Verify repeated dumps don't lose data (the original bug) + assert m.model_dump()["data"]["items"] == list(expected_validated) + assert m.model_dump()["data"]["items"] == list(expected_validated) + + +@pytest.mark.skipif(PYDANTIC_V1, reason="this is only supported in pydantic v2") +def test_iterable_construction_str_falls_back_to_list() -> None: + # str is iterable (over chars), but str(list_of_chars) produces the list's repr + # rather than reconstructing a string from items. We special-case str to fall + # back to list instead of attempting reconstruction. + class TypeWithIterable(TypedDict): + items: EagerIterable[str] + + class Model(BaseModel): + data: TypeWithIterable + + m = Model.model_validate({"data": {"items": "hello"}}) + + # falls back to list of chars rather than calling str(["h", "e", "l", "l", "o"]) + assert m.data["items"] == ["h", "e", "l", "l", "o"] + assert m.model_dump()["data"]["items"] == ["h", "e", "l", "l", "o"]