diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 26d064100..9616a91af 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.190.0" + ".": "4.191.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 82c7d1d90..33e07d1ac 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1 +1 @@ -configured_endpoints: 1410 +configured_endpoints: 1411 diff --git a/CHANGELOG.md b/CHANGELOG.md index 719a6fb0c..310c0f149 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [4.191.0](https://github.com/team-telnyx/telnyx-python/compare/v4.190.0...v4.191.0) (2026-11-02) + + +### Features + +* promote from staging e8c5468 ([abfe949](https://github.com/team-telnyx/telnyx-python/commit/abfe949caed764e6348954c70b4b38be5509878c)) + ## [4.190.0](https://github.com/team-telnyx/telnyx-python/compare/v4.189.0...v4.190.0) (2026-10-28) diff --git a/api.md b/api.md index 0805b3998..d256a92bb 100644 --- a/api.md +++ b/api.md @@ -721,7 +721,9 @@ from telnyx.types.ai import ( TelnyxAvatarSettings, ToolNode, ToolNodeReq, + TranscriptionChallenger, TranscriptionEndpointingPlan, + TranscriptionFallbackModel, TranscriptionSettings, TranscriptionSettingsConfig, TransferTool, @@ -1525,7 +1527,11 @@ Methods: Types: ```python -from telnyx.types.ai.memory.namespaces import NamespaceSettingsResponse +from telnyx.types.ai.memory.namespaces import ( + NamespaceSettings, + NamespaceSettingsResponse, + SummarySettings, +) ``` Methods: @@ -3702,6 +3708,8 @@ Types: from telnyx.types.phone_numbers import ( NumbersPhoneNumbersJob, PhoneNumbersJob, + PhoneNumbersJobPendingOperation, + PhoneNumbersJobSuccessfulOperation, JobRetrieveResponse, JobDeleteBatchResponse, JobUpdateBatchResponse, @@ -5089,11 +5097,13 @@ Types: ```python from telnyx.types import ( TelephonyCredential, + TokenMaterial, TelephonyCredentialCreateResponse, TelephonyCredentialRetrieveResponse, TelephonyCredentialUpdateResponse, TelephonyCredentialDeleteResponse, TelephonyCredentialCreateTokenResponse, + TelephonyCredentialRetrieveTokenMaterialResponse, ) ``` @@ -5105,6 +5115,7 @@ Methods: - client.telephony_credentials.list(\*\*params) -> SyncDefaultFlatPagination[TelephonyCredential] - client.telephony_credentials.delete(id) -> TelephonyCredentialDeleteResponse - client.telephony_credentials.create_token(id) -> str +- client.telephony_credentials.retrieve_token_material(id) -> TelephonyCredentialRetrieveTokenMaterialResponse # Texml @@ -6042,15 +6053,9 @@ Methods: ### PhoneNumbers -Types: - -```python -from telnyx.types.whatsapp.business_accounts import PhoneNumberListResponse -``` - Methods: -- client.whatsapp.business_accounts.phone_numbers.list(id, \*\*params) -> SyncDefaultFlatPagination[PhoneNumberListResponse] +- client.whatsapp.business_accounts.phone_numbers.list(id, \*\*params) -> SyncDefaultFlatPagination[WhatsappPhoneResponse] - client.whatsapp.business_accounts.phone_numbers.initialize_verification(id, \*\*params) -> None ### Settings @@ -6096,7 +6101,7 @@ Types: ```python from telnyx.types.whatsapp import ( - PhoneNumberListResponse, + WhatsappPhoneResponse, PhoneNumberGetResponse, PhoneNumberRetrieveConversationWindowResponse, PhoneNumberRetrievePhoneNumberResponse, @@ -6105,7 +6110,7 @@ from telnyx.types.whatsapp import ( Methods: -- client.whatsapp.phone_numbers.list(\*\*params) -> SyncDefaultFlatPagination[PhoneNumberListResponse] +- client.whatsapp.phone_numbers.list(\*\*params) -> SyncDefaultFlatPagination[WhatsappPhoneResponse] - client.whatsapp.phone_numbers.delete(phone_number) -> None - client.whatsapp.phone_numbers.get(\*\*params) -> PhoneNumberGetResponse - client.whatsapp.phone_numbers.resend_verification(phone_number, \*\*params) -> None @@ -6227,9 +6232,9 @@ Types: ```python from telnyx.types.whatsapp import ( + WhatsappHostedSignup, HostedSignupCreateResponse, HostedSignupRetrieveResponse, - HostedSignupListResponse, ) ``` @@ -6237,7 +6242,7 @@ Methods: - client.whatsapp.hosted_signups.create(\*\*params) -> HostedSignupCreateResponse - client.whatsapp.hosted_signups.retrieve(id) -> HostedSignupRetrieveResponse -- client.whatsapp.hosted_signups.list(\*\*params) -> SyncDefaultFlatPagination[HostedSignupListResponse] +- client.whatsapp.hosted_signups.list(\*\*params) -> SyncDefaultFlatPagination[WhatsappHostedSignup] # WhatsappMessageTemplates @@ -6458,6 +6463,7 @@ Types: ```python from telnyx.types.enterprises.reputation import ( + ExternalVerification, ExternalVerificationStatus, ExternalVerificationWrapped, ) @@ -6480,7 +6486,10 @@ Methods: Types: ```python -from telnyx.types.enterprises import EnterpriseEmailVerificationStatusWrapped +from telnyx.types.enterprises import ( + EnterpriseEmailVerificationStatus, + EnterpriseEmailVerificationStatusWrapped, +) ``` Methods: @@ -6859,7 +6868,7 @@ from telnyx.types import ( Methods: -- client.email_events.list(\*\*params) -> EmailEventListResponse +- client.email_events.list(\*\*params) -> SyncEmailEventsCursorPagination[EmailEventListResponse] - client.email_events.retrieve_stats(\*\*params) -> EmailEventRetrieveStatsResponse # EmailInboxes @@ -7058,6 +7067,7 @@ from telnyx.types import ( EmailTemplateCommon, EmailTemplateResponse, UpdateEmailTemplateRequest, + VariableSchemaEntry, EmailTemplateRenderResponse, ) ``` @@ -7305,7 +7315,7 @@ Methods: Types: ```python -from telnyx.types.compute.funcs import FuncLogExportConfigResponse +from telnyx.types.compute.funcs import FuncLogExportConfig, FuncLogExportConfigResponse ``` Methods: diff --git a/pyproject.toml b/pyproject.toml index 6c74bae8d..52cba10f4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "telnyx" -version = "4.190.0" +version = "4.191.0" description = "The official Python library for the telnyx API" dynamic = ["readme"] license = "MIT" diff --git a/src/telnyx/_version.py b/src/telnyx/_version.py index f553758f4..71cfe1dcb 100644 --- a/src/telnyx/_version.py +++ b/src/telnyx/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "telnyx" -__version__ = "4.190.0" # x-release-please-version +__version__ = "4.191.0" # x-release-please-version diff --git a/src/telnyx/pagination.py b/src/telnyx/pagination.py index e3c3b0a4c..52d6dabd8 100644 --- a/src/telnyx/pagination.py +++ b/src/telnyx/pagination.py @@ -37,6 +37,9 @@ "EmailCursorPaginationMeta", "SyncEmailCursorPagination", "AsyncEmailCursorPagination", + "EmailEventsCursorPaginationMeta", + "SyncEmailEventsCursorPagination", + "AsyncEmailEventsCursorPagination", "EmailBracketCursorPaginationMeta", "SyncEmailBracketCursorPagination", "AsyncEmailBracketCursorPagination", @@ -593,6 +596,56 @@ def next_page_info(self) -> Optional[PageInfo]: return PageInfo(params={"page_cursor": page_cursor}) +class EmailEventsCursorPaginationMeta(BaseModel): + page_cursor: Optional[str] = None + + +class SyncEmailEventsCursorPagination(BaseSyncPage[_T], BasePage[_T], Generic[_T]): + data: List[_T] + meta: Optional[EmailEventsCursorPaginationMeta] = None + + @override + def _get_page_items(self) -> List[_T]: + data = self.data + if not data: + return [] + return data + + @override + def next_page_info(self) -> Optional[PageInfo]: + page_cursor = None + if self.meta is not None: + if self.meta.page_cursor is not None: + page_cursor = self.meta.page_cursor + if not page_cursor: + return None + + return PageInfo(params={"page[cursor]": page_cursor}) + + +class AsyncEmailEventsCursorPagination(BaseAsyncPage[_T], BasePage[_T], Generic[_T]): + data: List[_T] + meta: Optional[EmailEventsCursorPaginationMeta] = None + + @override + def _get_page_items(self) -> List[_T]: + data = self.data + if not data: + return [] + return data + + @override + def next_page_info(self) -> Optional[PageInfo]: + page_cursor = None + if self.meta is not None: + if self.meta.page_cursor is not None: + page_cursor = self.meta.page_cursor + if not page_cursor: + return None + + return PageInfo(params={"page[cursor]": page_cursor}) + + class EmailBracketCursorPaginationMeta(BaseModel): page_cursor: Optional[str] = None diff --git a/src/telnyx/resources/browser_sessions/browser_sessions.py b/src/telnyx/resources/browser_sessions/browser_sessions.py index bc0b114cc..47ac13ef5 100644 --- a/src/telnyx/resources/browser_sessions/browser_sessions.py +++ b/src/telnyx/resources/browser_sessions/browser_sessions.py @@ -2,6 +2,7 @@ from __future__ import annotations +from typing import Dict from typing_extensions import Literal import httpx @@ -68,7 +69,7 @@ def create( policy: browser_session_create_params.Policy, idempotency_key: str | Omit = omit, limits: browser_session_create_params.Limits | Omit = omit, - metadata: object | Omit = omit, + metadata: Dict[str, object] | 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, @@ -289,7 +290,7 @@ async def create( policy: browser_session_create_params.Policy, idempotency_key: str | Omit = omit, limits: browser_session_create_params.Limits | Omit = omit, - metadata: object | Omit = omit, + metadata: Dict[str, object] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, diff --git a/src/telnyx/resources/email_events.py b/src/telnyx/resources/email_events.py index db18737ae..88dad6d07 100644 --- a/src/telnyx/resources/email_events.py +++ b/src/telnyx/resources/email_events.py @@ -18,7 +18,8 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) -from .._base_client import make_request_options +from ..pagination import SyncEmailEventsCursorPagination, AsyncEmailEventsCursorPagination +from .._base_client import AsyncPaginator, make_request_options from ..types.email_event_list_response import EmailEventListResponse from ..types.email_event_retrieve_stats_response import EmailEventRetrieveStatsResponse @@ -62,7 +63,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> EmailEventListResponse: + ) -> SyncEmailEventsCursorPagination[EmailEventListResponse]: """ Lists account-level email events sorted oldest first by `occurred_at asc, id asc`. Each row contains a legacy email.-prefixed event_type @@ -118,8 +119,9 @@ def list( timeout: Override the client-level default timeout for this request, in seconds """ - return self._get( + return self._get_api_list( "/email_events", + page=SyncEmailEventsCursorPagination[EmailEventListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -137,7 +139,7 @@ def list( email_event_list_params.EmailEventListParams, ), ), - cast_to=EmailEventListResponse, + model=EmailEventListResponse, ) def retrieve_stats( @@ -212,7 +214,7 @@ def with_streaming_response(self) -> AsyncEmailEventsResourceWithStreamingRespon """ return AsyncEmailEventsResourceWithStreamingResponse(self) - async def list( + def list( self, *, email_id: str | Omit = omit, @@ -227,7 +229,7 @@ async def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> EmailEventListResponse: + ) -> AsyncPaginator[EmailEventListResponse, AsyncEmailEventsCursorPagination[EmailEventListResponse]]: """ Lists account-level email events sorted oldest first by `occurred_at asc, id asc`. Each row contains a legacy email.-prefixed event_type @@ -283,14 +285,15 @@ async def list( timeout: Override the client-level default timeout for this request, in seconds """ - return await self._get( + return self._get_api_list( "/email_events", + page=AsyncEmailEventsCursorPagination[EmailEventListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "email_id": email_id, "event_type": event_type, @@ -302,7 +305,7 @@ async def list( email_event_list_params.EmailEventListParams, ), ), - cast_to=EmailEventListResponse, + model=EmailEventListResponse, ) async def retrieve_stats( diff --git a/src/telnyx/resources/email_templates.py b/src/telnyx/resources/email_templates.py index 7ab0e793d..432da78b4 100644 --- a/src/telnyx/resources/email_templates.py +++ b/src/telnyx/resources/email_templates.py @@ -28,6 +28,7 @@ from .._base_client import AsyncPaginator, make_request_options from ..types.email_template import EmailTemplate from ..types.email_template_response import EmailTemplateResponse +from ..types.variable_schema_entry_param import VariableSchemaEntryParam from ..types.email_template_render_response import EmailTemplateRenderResponse __all__ = ["EmailTemplatesResource", "AsyncEmailTemplatesResource"] @@ -64,7 +65,7 @@ def create( strict_variables: bool | Omit = omit, subject: Optional[str] | Omit = omit, text_body: Optional[str] | Omit = omit, - variable_schema: Optional[Dict[str, email_template_create_params.VariableSchema]] | Omit = omit, + variable_schema: Optional[Dict[str, VariableSchemaEntryParam]] | Omit = omit, variables: Optional[SequenceNotStr[str]] | Omit = omit, variables_mode: Literal["automatic", "explicit"] | Omit = omit, idempotency_key: str | Omit = omit, @@ -198,7 +199,7 @@ def update( strict_variables: bool | Omit = omit, subject: Optional[str] | Omit = omit, text_body: Optional[str] | Omit = omit, - variable_schema: Optional[Dict[str, email_template_update_params.VariableSchema]] | Omit = omit, + variable_schema: Optional[Dict[str, VariableSchemaEntryParam]] | Omit = omit, variables: Optional[SequenceNotStr[str]] | Omit = omit, variables_mode: Literal["automatic", "explicit"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -441,7 +442,7 @@ def replace( strict_variables: bool | Omit = omit, subject: Optional[str] | Omit = omit, text_body: Optional[str] | Omit = omit, - variable_schema: Optional[Dict[str, email_template_replace_params.VariableSchema]] | Omit = omit, + variable_schema: Optional[Dict[str, VariableSchemaEntryParam]] | Omit = omit, variables: Optional[SequenceNotStr[str]] | Omit = omit, variables_mode: Literal["automatic", "explicit"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -545,7 +546,7 @@ async def create( strict_variables: bool | Omit = omit, subject: Optional[str] | Omit = omit, text_body: Optional[str] | Omit = omit, - variable_schema: Optional[Dict[str, email_template_create_params.VariableSchema]] | Omit = omit, + variable_schema: Optional[Dict[str, VariableSchemaEntryParam]] | Omit = omit, variables: Optional[SequenceNotStr[str]] | Omit = omit, variables_mode: Literal["automatic", "explicit"] | Omit = omit, idempotency_key: str | Omit = omit, @@ -679,7 +680,7 @@ async def update( strict_variables: bool | Omit = omit, subject: Optional[str] | Omit = omit, text_body: Optional[str] | Omit = omit, - variable_schema: Optional[Dict[str, email_template_update_params.VariableSchema]] | Omit = omit, + variable_schema: Optional[Dict[str, VariableSchemaEntryParam]] | Omit = omit, variables: Optional[SequenceNotStr[str]] | Omit = omit, variables_mode: Literal["automatic", "explicit"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -922,7 +923,7 @@ async def replace( strict_variables: bool | Omit = omit, subject: Optional[str] | Omit = omit, text_body: Optional[str] | Omit = omit, - variable_schema: Optional[Dict[str, email_template_replace_params.VariableSchema]] | Omit = omit, + variable_schema: Optional[Dict[str, VariableSchemaEntryParam]] | Omit = omit, variables: Optional[SequenceNotStr[str]] | Omit = omit, variables_mode: Literal["automatic", "explicit"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. diff --git a/src/telnyx/resources/portouts/portouts.py b/src/telnyx/resources/portouts/portouts.py index d75760c26..af144a7e7 100644 --- a/src/telnyx/resources/portouts/portouts.py +++ b/src/telnyx/resources/portouts/portouts.py @@ -147,8 +147,10 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncDefaultFlatPagination[PortoutDetails]: - """ - Returns the portout requests according to filters + """Returns the portout requests according to filters. + + Carrier Port Out API + available. Please contact porting@telnyx.com. Args: filter: @@ -369,8 +371,10 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[PortoutDetails, AsyncDefaultFlatPagination[PortoutDetails]]: - """ - Returns the portout requests according to filters + """Returns the portout requests according to filters. + + Carrier Port Out API + available. Please contact porting@telnyx.com. Args: filter: diff --git a/src/telnyx/resources/telephony_credentials.py b/src/telnyx/resources/telephony_credentials.py index 0ceb0efef..a022e1497 100644 --- a/src/telnyx/resources/telephony_credentials.py +++ b/src/telnyx/resources/telephony_credentials.py @@ -26,6 +26,9 @@ from ..types.telephony_credential_delete_response import TelephonyCredentialDeleteResponse from ..types.telephony_credential_update_response import TelephonyCredentialUpdateResponse from ..types.telephony_credential_retrieve_response import TelephonyCredentialRetrieveResponse +from ..types.telephony_credential_retrieve_token_material_response import ( + TelephonyCredentialRetrieveTokenMaterialResponse, +) __all__ = ["TelephonyCredentialsResource", "AsyncTelephonyCredentialsResource"] @@ -305,6 +308,42 @@ def create_token( cast_to=str, ) + def retrieve_token_material( + self, + 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, + ) -> TelephonyCredentialRetrieveTokenMaterialResponse: + """ + Returns the material a server needs to mint login tokens for the credential + locally, with no request per token: `kid`, `tel_token` and `signing_secret`. The + same material is in the response of `POST /telephony_credentials`. Treat it like + the SIP password. + + 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 id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return self._get( + path_template("/telephony_credentials/{id}/token_material", id=id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=TelephonyCredentialRetrieveTokenMaterialResponse, + ) + class AsyncTelephonyCredentialsResource(AsyncAPIResource): @cached_property @@ -581,6 +620,42 @@ async def create_token( cast_to=str, ) + async def retrieve_token_material( + self, + 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, + ) -> TelephonyCredentialRetrieveTokenMaterialResponse: + """ + Returns the material a server needs to mint login tokens for the credential + locally, with no request per token: `kid`, `tel_token` and `signing_secret`. The + same material is in the response of `POST /telephony_credentials`. Treat it like + the SIP password. + + 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 id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return await self._get( + path_template("/telephony_credentials/{id}/token_material", id=id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=TelephonyCredentialRetrieveTokenMaterialResponse, + ) + class TelephonyCredentialsResourceWithRawResponse: def __init__(self, telephony_credentials: TelephonyCredentialsResource) -> None: @@ -604,6 +679,9 @@ def __init__(self, telephony_credentials: TelephonyCredentialsResource) -> None: self.create_token = to_raw_response_wrapper( telephony_credentials.create_token, ) + self.retrieve_token_material = to_raw_response_wrapper( + telephony_credentials.retrieve_token_material, + ) class AsyncTelephonyCredentialsResourceWithRawResponse: @@ -628,6 +706,9 @@ def __init__(self, telephony_credentials: AsyncTelephonyCredentialsResource) -> self.create_token = async_to_raw_response_wrapper( telephony_credentials.create_token, ) + self.retrieve_token_material = async_to_raw_response_wrapper( + telephony_credentials.retrieve_token_material, + ) class TelephonyCredentialsResourceWithStreamingResponse: @@ -652,6 +733,9 @@ def __init__(self, telephony_credentials: TelephonyCredentialsResource) -> None: self.create_token = to_streamed_response_wrapper( telephony_credentials.create_token, ) + self.retrieve_token_material = to_streamed_response_wrapper( + telephony_credentials.retrieve_token_material, + ) class AsyncTelephonyCredentialsResourceWithStreamingResponse: @@ -676,3 +760,6 @@ def __init__(self, telephony_credentials: AsyncTelephonyCredentialsResource) -> self.create_token = async_to_streamed_response_wrapper( telephony_credentials.create_token, ) + self.retrieve_token_material = async_to_streamed_response_wrapper( + telephony_credentials.retrieve_token_material, + ) diff --git a/src/telnyx/resources/voice_clones.py b/src/telnyx/resources/voice_clones.py index 3ba8c8608..76c44e2ef 100644 --- a/src/telnyx/resources/voice_clones.py +++ b/src/telnyx/resources/voice_clones.py @@ -155,7 +155,7 @@ def list( filter_model_id: Literal["Qwen3TTS", "Ultra", "Bayan", "speech-2.8-turbo", "Pro", "Turbo", "Urdu"] | Omit = omit, filter_name: str | Omit = omit, - filter_provider: Literal["telnyx", "minimax"] | Omit = omit, + filter_provider: Literal["telnyx", "minimax", "resemble"] | Omit = omit, page_number: int | Omit = omit, page_size: int | Omit = omit, sort: Literal["name", "-name", "created_at", "-created_at"] | Omit = omit, @@ -453,7 +453,7 @@ def list( filter_model_id: Literal["Qwen3TTS", "Ultra", "Bayan", "speech-2.8-turbo", "Pro", "Turbo", "Urdu"] | Omit = omit, filter_name: str | Omit = omit, - filter_provider: Literal["telnyx", "minimax"] | Omit = omit, + filter_provider: Literal["telnyx", "minimax", "resemble"] | Omit = omit, page_number: int | Omit = omit, page_size: int | Omit = omit, sort: Literal["name", "-name", "created_at", "-created_at"] | Omit = omit, diff --git a/src/telnyx/resources/whatsapp/business_accounts/phone_numbers.py b/src/telnyx/resources/whatsapp/business_accounts/phone_numbers.py index 78561c461..1c0de1349 100644 --- a/src/telnyx/resources/whatsapp/business_accounts/phone_numbers.py +++ b/src/telnyx/resources/whatsapp/business_accounts/phone_numbers.py @@ -19,7 +19,7 @@ from ....pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination from ...._base_client import AsyncPaginator, make_request_options from ....types.whatsapp.business_accounts import phone_number_list_params, phone_number_initialize_verification_params -from ....types.whatsapp.business_accounts.phone_number_list_response import PhoneNumberListResponse +from ....types.whatsapp.whatsapp_phone_response import WhatsappPhoneResponse __all__ = ["PhoneNumbersResource", "AsyncPhoneNumbersResource"] @@ -56,7 +56,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncDefaultFlatPagination[PhoneNumberListResponse]: + ) -> SyncDefaultFlatPagination[WhatsappPhoneResponse]: """ Returns phone numbers registered under the specified WhatsApp Business Account. @@ -73,7 +73,7 @@ def list( raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get_api_list( path_template("/v2/whatsapp/business_accounts/{id}/phone_numbers", id=id), - page=SyncDefaultFlatPagination[PhoneNumberListResponse], + page=SyncDefaultFlatPagination[WhatsappPhoneResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -87,7 +87,7 @@ def list( phone_number_list_params.PhoneNumberListParams, ), ), - model=PhoneNumberListResponse, + model=WhatsappPhoneResponse, ) def initialize_verification( @@ -171,7 +171,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[PhoneNumberListResponse, AsyncDefaultFlatPagination[PhoneNumberListResponse]]: + ) -> AsyncPaginator[WhatsappPhoneResponse, AsyncDefaultFlatPagination[WhatsappPhoneResponse]]: """ Returns phone numbers registered under the specified WhatsApp Business Account. @@ -188,7 +188,7 @@ def list( raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get_api_list( path_template("/v2/whatsapp/business_accounts/{id}/phone_numbers", id=id), - page=AsyncDefaultFlatPagination[PhoneNumberListResponse], + page=AsyncDefaultFlatPagination[WhatsappPhoneResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -202,7 +202,7 @@ def list( phone_number_list_params.PhoneNumberListParams, ), ), - model=PhoneNumberListResponse, + model=WhatsappPhoneResponse, ) async def initialize_verification( diff --git a/src/telnyx/resources/whatsapp/hosted_signups.py b/src/telnyx/resources/whatsapp/hosted_signups.py index 88850f874..ce961a91f 100644 --- a/src/telnyx/resources/whatsapp/hosted_signups.py +++ b/src/telnyx/resources/whatsapp/hosted_signups.py @@ -21,7 +21,7 @@ from ...pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination from ..._base_client import AsyncPaginator, make_request_options from ...types.whatsapp import hosted_signup_list_params, hosted_signup_create_params -from ...types.whatsapp.hosted_signup_list_response import HostedSignupListResponse +from ...types.whatsapp.whatsapp_hosted_signup import WhatsappHostedSignup from ...types.whatsapp.hosted_signup_create_response import HostedSignupCreateResponse from ...types.whatsapp.hosted_signup_retrieve_response import HostedSignupRetrieveResponse @@ -145,7 +145,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncDefaultFlatPagination[HostedSignupListResponse]: + ) -> SyncDefaultFlatPagination[WhatsappHostedSignup]: """List hosted signups created by the account, newest first. Expired hosted signups @@ -162,7 +162,7 @@ def list( """ return self._get_api_list( "/whatsapp/hosted_signups", - page=SyncDefaultFlatPagination[HostedSignupListResponse], + page=SyncDefaultFlatPagination[WhatsappHostedSignup], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -176,7 +176,7 @@ def list( hosted_signup_list_params.HostedSignupListParams, ), ), - model=HostedSignupListResponse, + model=WhatsappHostedSignup, ) @@ -297,7 +297,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[HostedSignupListResponse, AsyncDefaultFlatPagination[HostedSignupListResponse]]: + ) -> AsyncPaginator[WhatsappHostedSignup, AsyncDefaultFlatPagination[WhatsappHostedSignup]]: """List hosted signups created by the account, newest first. Expired hosted signups @@ -314,7 +314,7 @@ def list( """ return self._get_api_list( "/whatsapp/hosted_signups", - page=AsyncDefaultFlatPagination[HostedSignupListResponse], + page=AsyncDefaultFlatPagination[WhatsappHostedSignup], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -328,7 +328,7 @@ def list( hosted_signup_list_params.HostedSignupListParams, ), ), - model=HostedSignupListResponse, + model=WhatsappHostedSignup, ) diff --git a/src/telnyx/resources/whatsapp/phone_numbers/phone_numbers.py b/src/telnyx/resources/whatsapp/phone_numbers/phone_numbers.py index d801cdbf1..aef591267 100644 --- a/src/telnyx/resources/whatsapp/phone_numbers/phone_numbers.py +++ b/src/telnyx/resources/whatsapp/phone_numbers/phone_numbers.py @@ -57,8 +57,8 @@ ConversationalComponentsResourceWithStreamingResponse, AsyncConversationalComponentsResourceWithStreamingResponse, ) +from ....types.whatsapp.whatsapp_phone_response import WhatsappPhoneResponse from ....types.whatsapp.phone_number_get_response import PhoneNumberGetResponse -from ....types.whatsapp.phone_number_list_response import PhoneNumberListResponse from ....types.whatsapp.phone_number_retrieve_phone_number_response import PhoneNumberRetrievePhoneNumberResponse from ....types.whatsapp.phone_number_retrieve_conversation_window_response import ( PhoneNumberRetrieveConversationWindowResponse, @@ -120,7 +120,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncDefaultFlatPagination[PhoneNumberListResponse]: + ) -> SyncDefaultFlatPagination[WhatsappPhoneResponse]: """ Returns WhatsApp phone numbers linked to the authenticated Telnyx account. @@ -135,7 +135,7 @@ def list( """ return self._get_api_list( "/v2/whatsapp/phone_numbers", - page=SyncDefaultFlatPagination[PhoneNumberListResponse], + page=SyncDefaultFlatPagination[WhatsappPhoneResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -149,7 +149,7 @@ def list( phone_number_list_params.PhoneNumberListParams, ), ), - model=PhoneNumberListResponse, + model=WhatsappPhoneResponse, ) def delete( @@ -437,7 +437,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[PhoneNumberListResponse, AsyncDefaultFlatPagination[PhoneNumberListResponse]]: + ) -> AsyncPaginator[WhatsappPhoneResponse, AsyncDefaultFlatPagination[WhatsappPhoneResponse]]: """ Returns WhatsApp phone numbers linked to the authenticated Telnyx account. @@ -452,7 +452,7 @@ def list( """ return self._get_api_list( "/v2/whatsapp/phone_numbers", - page=AsyncDefaultFlatPagination[PhoneNumberListResponse], + page=AsyncDefaultFlatPagination[WhatsappPhoneResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -466,7 +466,7 @@ def list( phone_number_list_params.PhoneNumberListParams, ), ), - model=PhoneNumberListResponse, + model=WhatsappPhoneResponse, ) async def delete( diff --git a/src/telnyx/types/__init__.py b/src/telnyx/types/__init__.py index b1a64ed2c..fd8e9d3c3 100644 --- a/src/telnyx/types/__init__.py +++ b/src/telnyx/types/__init__.py @@ -126,6 +126,7 @@ from .settings_param import SettingsParam as SettingsParam from .sim_card_group import SimCardGroup as SimCardGroup from .sim_card_order import SimCardOrder as SimCardOrder +from .token_material import TokenMaterial as TokenMaterial from .uac_connection import UacConnection as UacConnection from .verify_profile import VerifyProfile as VerifyProfile from .whatsapp_media import WhatsappMedia as WhatsappMedia @@ -329,6 +330,7 @@ from .s3_configuration_data import S3ConfigurationData as S3ConfigurationData from .uac_external_settings import UacExternalSettings as UacExternalSettings from .uac_internal_settings import UacInternalSettings as UacInternalSettings +from .variable_schema_entry import VariableSchemaEntry as VariableSchemaEntry from .voice_design_response import VoiceDesignResponse as VoiceDesignResponse from .voice_sdk_call_report import VoiceSDKCallReport as VoiceSDKCallReport from .whatsapp_message_echo import WhatsappMessageEcho as WhatsappMessageEcho @@ -608,6 +610,7 @@ from .uac_internal_settings_param import UacInternalSettingsParam as UacInternalSettingsParam from .unsafe_unwrap_webhook_event import UnsafeUnwrapWebhookEvent as UnsafeUnwrapWebhookEvent from .user_addresses_user_address import UserAddressesUserAddress as UserAddressesUserAddress +from .variable_schema_entry_param import VariableSchemaEntryParam as VariableSchemaEntryParam from .verified_number_list_params import VerifiedNumberListParams as VerifiedNumberListParams from .wireless_wireless_blocklist import WirelessWirelessBlocklist as WirelessWirelessBlocklist from .advanced_order_create_params import AdvancedOrderCreateParams as AdvancedOrderCreateParams @@ -1795,6 +1798,9 @@ from .messaging_profile_list_alphanumeric_sender_ids_params import ( MessagingProfileListAlphanumericSenderIDsParams as MessagingProfileListAlphanumericSenderIDsParams, ) +from .telephony_credential_retrieve_token_material_response import ( + TelephonyCredentialRetrieveTokenMaterialResponse as TelephonyCredentialRetrieveTokenMaterialResponse, +) from .messaging_hosted_number_order_check_eligibility_params import ( MessagingHostedNumberOrderCheckEligibilityParams as MessagingHostedNumberOrderCheckEligibilityParams, ) diff --git a/src/telnyx/types/ai/__init__.py b/src/telnyx/types/ai/__init__.py index 8ffb337a6..4489830aa 100644 --- a/src/telnyx/types/ai/__init__.py +++ b/src/telnyx/types/ai/__init__.py @@ -85,9 +85,11 @@ from .avatar_settings_request_param import AvatarSettingsRequestParam as AvatarSettingsRequestParam from .mission_update_mission_params import MissionUpdateMissionParams as MissionUpdateMissionParams from .openai_create_response_params import OpenAICreateResponseParams as OpenAICreateResponseParams +from .transcription_challenger_param import TranscriptionChallengerParam as TranscriptionChallengerParam from .conversation_add_message_params import ConversationAddMessageParams as ConversationAddMessageParams from .openai_create_response_response import OpenAICreateResponseResponse as OpenAICreateResponseResponse from .embedding_similarity_search_params import EmbeddingSimilaritySearchParams as EmbeddingSimilaritySearchParams +from .transcription_fallback_model_param import TranscriptionFallbackModelParam as TranscriptionFallbackModelParam from .transcription_settings_config_param import TranscriptionSettingsConfigParam as TranscriptionSettingsConfigParam from .post_conversation_settings_req_param import PostConversationSettingsReqParam as PostConversationSettingsReqParam from .transcription_endpointing_plan_param import TranscriptionEndpointingPlanParam as TranscriptionEndpointingPlanParam @@ -153,6 +155,7 @@ from .audio_visualizer_config import AudioVisualizerConfig as AudioVisualizerConfig from .embedding_list_response import EmbeddingListResponse as EmbeddingListResponse from .cluster_compute_response import ClusterComputeResponse as ClusterComputeResponse + from .transcription_challenger import TranscriptionChallenger as TranscriptionChallenger from .assistant_delete_response import AssistantDeleteResponse as AssistantDeleteResponse from .audio_transcribe_response import AudioTranscribeResponse as AudioTranscribeResponse from .cluster_retrieve_response import ClusterRetrieveResponse as ClusterRetrieveResponse @@ -163,6 +166,7 @@ from .assistant_whatsapp_response import AssistantWhatsappResponse as AssistantWhatsappResponse from .embedding_retrieve_response import EmbeddingRetrieveResponse as EmbeddingRetrieveResponse from .conversation_update_response import ConversationUpdateResponse as ConversationUpdateResponse + from .transcription_fallback_model import TranscriptionFallbackModel as TranscriptionFallbackModel from .transcription_settings_config import TranscriptionSettingsConfig as TranscriptionSettingsConfig from .conversation_retrieve_response import ConversationRetrieveResponse as ConversationRetrieveResponse from .transcription_endpointing_plan import TranscriptionEndpointingPlan as TranscriptionEndpointingPlan @@ -302,10 +306,18 @@ def __getattr__(name: str) -> Any: from .tool_node import ToolNode return ToolNode + if name == "TranscriptionChallenger": + from .transcription_challenger import TranscriptionChallenger + + return TranscriptionChallenger if name == "TranscriptionEndpointingPlan": from .transcription_endpointing_plan import TranscriptionEndpointingPlan return TranscriptionEndpointingPlan + if name == "TranscriptionFallbackModel": + from .transcription_fallback_model import TranscriptionFallbackModel + + return TranscriptionFallbackModel if name == "TranscriptionSettings": from .transcription_settings import TranscriptionSettings diff --git a/src/telnyx/types/ai/memory/namespaces/__init__.py b/src/telnyx/types/ai/memory/namespaces/__init__.py index dc9cdc966..456141a72 100644 --- a/src/telnyx/types/ai/memory/namespaces/__init__.py +++ b/src/telnyx/types/ai/memory/namespaces/__init__.py @@ -13,6 +13,8 @@ if TYPE_CHECKING: from .page_meta import PageMeta as PageMeta + from .summary_settings import SummarySettings as SummarySettings + from .namespace_settings import NamespaceSettings as NamespaceSettings from .profile_list_response import ProfileListResponse as ProfileListResponse from .profile_delete_response import ProfileDeleteResponse as ProfileDeleteResponse from .profile_ingest_response import ProfileIngestResponse as ProfileIngestResponse @@ -56,8 +58,16 @@ def __getattr__(name: str) -> Any: from .profile_retrieve_summary_response import ProfileRetrieveSummaryResponse return ProfileRetrieveSummaryResponse + if name == "NamespaceSettings": + from .namespace_settings import NamespaceSettings + + return NamespaceSettings if name == "NamespaceSettingsResponse": from .namespace_settings_response import NamespaceSettingsResponse return NamespaceSettingsResponse + if name == "SummarySettings": + from .summary_settings import SummarySettings + + return SummarySettings raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/src/telnyx/types/ai/memory/namespaces/namespace_settings.py b/src/telnyx/types/ai/memory/namespaces/namespace_settings.py new file mode 100644 index 000000000..93e7ea45b --- /dev/null +++ b/src/telnyx/types/ai/memory/namespaces/namespace_settings.py @@ -0,0 +1,17 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional + +from ....._models import BaseModel +from .summary_settings import SummarySettings + +__all__ = ["NamespaceSettings"] + + +class NamespaceSettings(BaseModel): + """A namespace's settings, grouped by what they affect.""" + + summary: Optional[SummarySettings] = None + """Settings that shape this namespace's summaries.""" diff --git a/src/telnyx/types/ai/memory/namespaces/namespace_settings_response.py b/src/telnyx/types/ai/memory/namespaces/namespace_settings_response.py index df8dddb10..7364e69c3 100644 --- a/src/telnyx/types/ai/memory/namespaces/namespace_settings_response.py +++ b/src/telnyx/types/ai/memory/namespaces/namespace_settings_response.py @@ -2,35 +2,12 @@ from __future__ import annotations -from typing import Optional - from ....._models import BaseModel +from .namespace_settings import NamespaceSettings -__all__ = ["NamespaceSettingsResponse", "Data", "DataSummary"] - - -class DataSummary(BaseModel): - """Settings that shape this namespace's summaries.""" - - instructions: Optional[str] = None - """ - Free-form instructions that influence how this namespace's summaries are - written, shared by every profile in the namespace. How you use them is up to you - -- they steer the outcome, so try a phrasing and see how the summary comes out. - Advisory: they steer the summary but never override or deny a profile's own - facts, and they do not affect recall. Null or empty means none are set, and - summaries use the neutral default. A change reaches each summary the next time - it is regenerated. - """ - - -class Data(BaseModel): - """A namespace's settings, grouped by what they affect.""" - - summary: Optional[DataSummary] = None - """Settings that shape this namespace's summaries.""" +__all__ = ["NamespaceSettingsResponse"] class NamespaceSettingsResponse(BaseModel): - data: Data + data: NamespaceSettings """A namespace's settings, grouped by what they affect.""" diff --git a/src/telnyx/types/ai/memory/namespaces/summary_settings.py b/src/telnyx/types/ai/memory/namespaces/summary_settings.py new file mode 100644 index 000000000..13a271db4 --- /dev/null +++ b/src/telnyx/types/ai/memory/namespaces/summary_settings.py @@ -0,0 +1,24 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional + +from ....._models import BaseModel + +__all__ = ["SummarySettings"] + + +class SummarySettings(BaseModel): + """A namespace's summary settings, shared by every profile in it.""" + + instructions: Optional[str] = None + """ + Free-form instructions that influence how this namespace's summaries are + written, shared by every profile in the namespace. How you use them is up to you + -- they steer the outcome, so try a phrasing and see how the summary comes out. + Advisory: they steer the summary but never override or deny a profile's own + facts, and they do not affect recall. Null or empty means none are set, and + summaries use the neutral default. A change reaches each summary the next time + it is regenerated. + """ diff --git a/src/telnyx/types/ai/pay_tool_params.py b/src/telnyx/types/ai/pay_tool_params.py index fd1826ba7..d3c2f8a4b 100644 --- a/src/telnyx/types/ai/pay_tool_params.py +++ b/src/telnyx/types/ai/pay_tool_params.py @@ -2,12 +2,280 @@ from __future__ import annotations -from typing import Dict, List, Optional +from typing import Dict, List, Union, Optional from typing_extensions import Literal +from pydantic import Field as FieldInfo + from ..._models import BaseModel -__all__ = ["PayToolParams"] +__all__ = [ + "PayToolParams", + "Prompts", + "PromptsBankAccountNumberUnionMember1", + "PromptsBankRoutingNumberUnionMember1", + "PromptsExpirationDateUnionMember1", + "PromptsPaymentCardNumberUnionMember1", + "PromptsPostalCodeUnionMember1", + "PromptsSecurityCodeUnionMember1", +] + + +class PromptsBankAccountNumberUnionMember1(BaseModel): + """ + A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema. + """ + + text: str + """Text spoken for the payment collection step.""" + + attempt: Optional[str] = None + """Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. + + `"2 3"`) for which this prompt applies. A prompt qualified with an attempt + number above `max_attempts` (default 3) is rejected at write time — it could + never play. + """ + + card_type: Optional[ + Literal["visa", "mastercard", "amex", "optima", "discover", "diners-club", "jcb", "maestro", "enroute"] + ] = None + """Lowercase, case-sensitive detected card type for which this prompt applies.""" + + error_type: Optional[ + Literal[ + "timeout", + "invalid-card-number", + "invalid-card-type", + "invalid-date", + "invalid-security-code", + "invalid-postal-code", + "invalid-bank-routing-number", + "invalid-bank-account-number", + "input-matching-failed", + ] + ] = None + """Step error for which this prompt applies.""" + + +class PromptsBankRoutingNumberUnionMember1(BaseModel): + """ + A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema. + """ + + text: str + """Text spoken for the payment collection step.""" + + attempt: Optional[str] = None + """Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. + + `"2 3"`) for which this prompt applies. A prompt qualified with an attempt + number above `max_attempts` (default 3) is rejected at write time — it could + never play. + """ + + card_type: Optional[ + Literal["visa", "mastercard", "amex", "optima", "discover", "diners-club", "jcb", "maestro", "enroute"] + ] = None + """Lowercase, case-sensitive detected card type for which this prompt applies.""" + + error_type: Optional[ + Literal[ + "timeout", + "invalid-card-number", + "invalid-card-type", + "invalid-date", + "invalid-security-code", + "invalid-postal-code", + "invalid-bank-routing-number", + "invalid-bank-account-number", + "input-matching-failed", + ] + ] = None + """Step error for which this prompt applies.""" + + +class PromptsExpirationDateUnionMember1(BaseModel): + """ + A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema. + """ + + text: str + """Text spoken for the payment collection step.""" + + attempt: Optional[str] = None + """Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. + + `"2 3"`) for which this prompt applies. A prompt qualified with an attempt + number above `max_attempts` (default 3) is rejected at write time — it could + never play. + """ + + card_type: Optional[ + Literal["visa", "mastercard", "amex", "optima", "discover", "diners-club", "jcb", "maestro", "enroute"] + ] = None + """Lowercase, case-sensitive detected card type for which this prompt applies.""" + + error_type: Optional[ + Literal[ + "timeout", + "invalid-card-number", + "invalid-card-type", + "invalid-date", + "invalid-security-code", + "invalid-postal-code", + "invalid-bank-routing-number", + "invalid-bank-account-number", + "input-matching-failed", + ] + ] = None + """Step error for which this prompt applies.""" + + +class PromptsPaymentCardNumberUnionMember1(BaseModel): + """ + A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema. + """ + + text: str + """Text spoken for the payment collection step.""" + + attempt: Optional[str] = None + """Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. + + `"2 3"`) for which this prompt applies. A prompt qualified with an attempt + number above `max_attempts` (default 3) is rejected at write time — it could + never play. + """ + + card_type: Optional[ + Literal["visa", "mastercard", "amex", "optima", "discover", "diners-club", "jcb", "maestro", "enroute"] + ] = None + """Lowercase, case-sensitive detected card type for which this prompt applies.""" + + error_type: Optional[ + Literal[ + "timeout", + "invalid-card-number", + "invalid-card-type", + "invalid-date", + "invalid-security-code", + "invalid-postal-code", + "invalid-bank-routing-number", + "invalid-bank-account-number", + "input-matching-failed", + ] + ] = None + """Step error for which this prompt applies.""" + + +class PromptsPostalCodeUnionMember1(BaseModel): + """ + A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema. + """ + + text: str + """Text spoken for the payment collection step.""" + + attempt: Optional[str] = None + """Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. + + `"2 3"`) for which this prompt applies. A prompt qualified with an attempt + number above `max_attempts` (default 3) is rejected at write time — it could + never play. + """ + + card_type: Optional[ + Literal["visa", "mastercard", "amex", "optima", "discover", "diners-club", "jcb", "maestro", "enroute"] + ] = None + """Lowercase, case-sensitive detected card type for which this prompt applies.""" + + error_type: Optional[ + Literal[ + "timeout", + "invalid-card-number", + "invalid-card-type", + "invalid-date", + "invalid-security-code", + "invalid-postal-code", + "invalid-bank-routing-number", + "invalid-bank-account-number", + "input-matching-failed", + ] + ] = None + """Step error for which this prompt applies.""" + + +class PromptsSecurityCodeUnionMember1(BaseModel): + """ + A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema. + """ + + text: str + """Text spoken for the payment collection step.""" + + attempt: Optional[str] = None + """Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. + + `"2 3"`) for which this prompt applies. A prompt qualified with an attempt + number above `max_attempts` (default 3) is rejected at write time — it could + never play. + """ + + card_type: Optional[ + Literal["visa", "mastercard", "amex", "optima", "discover", "diners-club", "jcb", "maestro", "enroute"] + ] = None + """Lowercase, case-sensitive detected card type for which this prompt applies.""" + + error_type: Optional[ + Literal[ + "timeout", + "invalid-card-number", + "invalid-card-type", + "invalid-date", + "invalid-security-code", + "invalid-postal-code", + "invalid-bank-routing-number", + "invalid-bank-account-number", + "input-matching-failed", + ] + ] = None + """Step error for which this prompt applies.""" + + +class Prompts(BaseModel): + """Custom text-to-speech prompts keyed by payment collection step. + + The AI assistant merges its own card-number prompt into this map, matching on the same step keys. + """ + + bank_account_number: Union[str, List[PromptsBankAccountNumberUnionMember1], None] = FieldInfo( + alias="bank-account-number", default=None + ) + """A default prompt string or an ordered list of qualified prompts.""" + + bank_routing_number: Union[str, List[PromptsBankRoutingNumberUnionMember1], None] = FieldInfo( + alias="bank-routing-number", default=None + ) + """A default prompt string or an ordered list of qualified prompts.""" + + expiration_date: Union[str, List[PromptsExpirationDateUnionMember1], None] = FieldInfo( + alias="expiration-date", default=None + ) + """A default prompt string or an ordered list of qualified prompts.""" + + payment_card_number: Union[str, List[PromptsPaymentCardNumberUnionMember1], None] = FieldInfo( + alias="payment-card-number", default=None + ) + """A default prompt string or an ordered list of qualified prompts.""" + + postal_code: Union[str, List[PromptsPostalCodeUnionMember1], None] = FieldInfo(alias="postal-code", default=None) + """A default prompt string or an ordered list of qualified prompts.""" + + security_code: Union[str, List[PromptsSecurityCodeUnionMember1], None] = FieldInfo( + alias="security-code", default=None + ) + """A default prompt string or an ordered list of qualified prompts.""" class PayToolParams(BaseModel): @@ -34,9 +302,54 @@ class PayToolParams(BaseModel): the assistant passes is what reaches the processor. """ + inter_digit_timeout_millis: Optional[int] = None + """Time in milliseconds to wait between consecutive DTMF digits. + + Omitted means the platform default (5000) applies. + """ + + max_attempts: Optional[int] = None + """Maximum number of attempts for each payment collection step. + + Omitted means the platform default (3) applies. + """ + + min_postal_code_length: Optional[int] = None + """ + Minimum number of digits the caller must enter when collecting a credit-card + billing postal code. Applies only when `postal_code` prompts the caller. Omitted + means the platform default (1) applies. The maximum number of digits collected + is the greater of 10 and this value. This does not validate the length of a + postal code supplied directly in `postal_code`. + """ + payment_method: Optional[str] = None """Default payment method for payments processed by this tool.""" + postal_code: Union[str, bool, None] = None + """Controls billing postal code collection for credit-card payments. + + Set to `false` to skip the postal code prompt without supplying a postal code to + the payment connector (non-US cards, e.g. Irish Eircodes). Set to `true` to + prompt the caller. Supply a non-empty string, such as `"90210"`, to use that + postal code without prompting. This option does not affect ACH debit payments or + payments using an existing token. + """ + + prompts: Optional[Prompts] = None + """Custom text-to-speech prompts keyed by payment collection step. + + The AI assistant merges its own card-number prompt into this map, matching on + the same step keys. + """ + + timeout_millis: Optional[int] = None + """Time in milliseconds to wait for DTMF input for each collection step. + + Omitted means the platform default (5000) applies. Increase this for slower + entry, e.g. a 16-digit card number. + """ + valid_card_types: Optional[ List[Literal["visa", "mastercard", "amex", "maestro", "discover", "optima", "jcb", "diners-club", "enroute"]] ] = None diff --git a/src/telnyx/types/ai/pay_tool_params_param.py b/src/telnyx/types/ai/pay_tool_params_param.py index ff83ef672..9489f7504 100644 --- a/src/telnyx/types/ai/pay_tool_params_param.py +++ b/src/telnyx/types/ai/pay_tool_params_param.py @@ -2,10 +2,252 @@ from __future__ import annotations -from typing import Dict, List, Optional -from typing_extensions import Literal, Required, TypedDict +from typing import Dict, List, Union, Iterable, Optional +from typing_extensions import Literal, Required, Annotated, TypedDict -__all__ = ["PayToolParamsParam"] +from ..._utils import PropertyInfo + +__all__ = [ + "PayToolParamsParam", + "Prompts", + "PromptsBankAccountNumberUnionMember1", + "PromptsBankRoutingNumberUnionMember1", + "PromptsExpirationDateUnionMember1", + "PromptsPaymentCardNumberUnionMember1", + "PromptsPostalCodeUnionMember1", + "PromptsSecurityCodeUnionMember1", +] + + +class PromptsBankAccountNumberUnionMember1(TypedDict, total=False): + """ + A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema. + """ + + text: Required[str] + """Text spoken for the payment collection step.""" + + attempt: str + """Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. + + `"2 3"`) for which this prompt applies. A prompt qualified with an attempt + number above `max_attempts` (default 3) is rejected at write time — it could + never play. + """ + + card_type: Literal["visa", "mastercard", "amex", "optima", "discover", "diners-club", "jcb", "maestro", "enroute"] + """Lowercase, case-sensitive detected card type for which this prompt applies.""" + + error_type: Literal[ + "timeout", + "invalid-card-number", + "invalid-card-type", + "invalid-date", + "invalid-security-code", + "invalid-postal-code", + "invalid-bank-routing-number", + "invalid-bank-account-number", + "input-matching-failed", + ] + """Step error for which this prompt applies.""" + + +class PromptsBankRoutingNumberUnionMember1(TypedDict, total=False): + """ + A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema. + """ + + text: Required[str] + """Text spoken for the payment collection step.""" + + attempt: str + """Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. + + `"2 3"`) for which this prompt applies. A prompt qualified with an attempt + number above `max_attempts` (default 3) is rejected at write time — it could + never play. + """ + + card_type: Literal["visa", "mastercard", "amex", "optima", "discover", "diners-club", "jcb", "maestro", "enroute"] + """Lowercase, case-sensitive detected card type for which this prompt applies.""" + + error_type: Literal[ + "timeout", + "invalid-card-number", + "invalid-card-type", + "invalid-date", + "invalid-security-code", + "invalid-postal-code", + "invalid-bank-routing-number", + "invalid-bank-account-number", + "input-matching-failed", + ] + """Step error for which this prompt applies.""" + + +class PromptsExpirationDateUnionMember1(TypedDict, total=False): + """ + A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema. + """ + + text: Required[str] + """Text spoken for the payment collection step.""" + + attempt: str + """Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. + + `"2 3"`) for which this prompt applies. A prompt qualified with an attempt + number above `max_attempts` (default 3) is rejected at write time — it could + never play. + """ + + card_type: Literal["visa", "mastercard", "amex", "optima", "discover", "diners-club", "jcb", "maestro", "enroute"] + """Lowercase, case-sensitive detected card type for which this prompt applies.""" + + error_type: Literal[ + "timeout", + "invalid-card-number", + "invalid-card-type", + "invalid-date", + "invalid-security-code", + "invalid-postal-code", + "invalid-bank-routing-number", + "invalid-bank-account-number", + "input-matching-failed", + ] + """Step error for which this prompt applies.""" + + +class PromptsPaymentCardNumberUnionMember1(TypedDict, total=False): + """ + A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema. + """ + + text: Required[str] + """Text spoken for the payment collection step.""" + + attempt: str + """Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. + + `"2 3"`) for which this prompt applies. A prompt qualified with an attempt + number above `max_attempts` (default 3) is rejected at write time — it could + never play. + """ + + card_type: Literal["visa", "mastercard", "amex", "optima", "discover", "diners-club", "jcb", "maestro", "enroute"] + """Lowercase, case-sensitive detected card type for which this prompt applies.""" + + error_type: Literal[ + "timeout", + "invalid-card-number", + "invalid-card-type", + "invalid-date", + "invalid-security-code", + "invalid-postal-code", + "invalid-bank-routing-number", + "invalid-bank-account-number", + "input-matching-failed", + ] + """Step error for which this prompt applies.""" + + +class PromptsPostalCodeUnionMember1(TypedDict, total=False): + """ + A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema. + """ + + text: Required[str] + """Text spoken for the payment collection step.""" + + attempt: str + """Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. + + `"2 3"`) for which this prompt applies. A prompt qualified with an attempt + number above `max_attempts` (default 3) is rejected at write time — it could + never play. + """ + + card_type: Literal["visa", "mastercard", "amex", "optima", "discover", "diners-club", "jcb", "maestro", "enroute"] + """Lowercase, case-sensitive detected card type for which this prompt applies.""" + + error_type: Literal[ + "timeout", + "invalid-card-number", + "invalid-card-type", + "invalid-date", + "invalid-security-code", + "invalid-postal-code", + "invalid-bank-routing-number", + "invalid-bank-account-number", + "input-matching-failed", + ] + """Step error for which this prompt applies.""" + + +class PromptsSecurityCodeUnionMember1(TypedDict, total=False): + """ + A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema. + """ + + text: Required[str] + """Text spoken for the payment collection step.""" + + attempt: str + """Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. + + `"2 3"`) for which this prompt applies. A prompt qualified with an attempt + number above `max_attempts` (default 3) is rejected at write time — it could + never play. + """ + + card_type: Literal["visa", "mastercard", "amex", "optima", "discover", "diners-club", "jcb", "maestro", "enroute"] + """Lowercase, case-sensitive detected card type for which this prompt applies.""" + + error_type: Literal[ + "timeout", + "invalid-card-number", + "invalid-card-type", + "invalid-date", + "invalid-security-code", + "invalid-postal-code", + "invalid-bank-routing-number", + "invalid-bank-account-number", + "input-matching-failed", + ] + """Step error for which this prompt applies.""" + + +class Prompts(TypedDict, total=False): + """Custom text-to-speech prompts keyed by payment collection step. + + The AI assistant merges its own card-number prompt into this map, matching on the same step keys. + """ + + bank_account_number: Annotated[ + Union[str, Iterable[PromptsBankAccountNumberUnionMember1]], PropertyInfo(alias="bank-account-number") + ] + """A default prompt string or an ordered list of qualified prompts.""" + + bank_routing_number: Annotated[ + Union[str, Iterable[PromptsBankRoutingNumberUnionMember1]], PropertyInfo(alias="bank-routing-number") + ] + """A default prompt string or an ordered list of qualified prompts.""" + + expiration_date: Annotated[ + Union[str, Iterable[PromptsExpirationDateUnionMember1]], PropertyInfo(alias="expiration-date") + ] + """A default prompt string or an ordered list of qualified prompts.""" + + payment_card_number: Annotated[ + Union[str, Iterable[PromptsPaymentCardNumberUnionMember1]], PropertyInfo(alias="payment-card-number") + ] + """A default prompt string or an ordered list of qualified prompts.""" + + postal_code: Annotated[Union[str, Iterable[PromptsPostalCodeUnionMember1]], PropertyInfo(alias="postal-code")] + """A default prompt string or an ordered list of qualified prompts.""" + + security_code: Annotated[Union[str, Iterable[PromptsSecurityCodeUnionMember1]], PropertyInfo(alias="security-code")] + """A default prompt string or an ordered list of qualified prompts.""" class PayToolParamsParam(TypedDict, total=False): @@ -32,9 +274,54 @@ class PayToolParamsParam(TypedDict, total=False): the assistant passes is what reaches the processor. """ + inter_digit_timeout_millis: int + """Time in milliseconds to wait between consecutive DTMF digits. + + Omitted means the platform default (5000) applies. + """ + + max_attempts: int + """Maximum number of attempts for each payment collection step. + + Omitted means the platform default (3) applies. + """ + + min_postal_code_length: int + """ + Minimum number of digits the caller must enter when collecting a credit-card + billing postal code. Applies only when `postal_code` prompts the caller. Omitted + means the platform default (1) applies. The maximum number of digits collected + is the greater of 10 and this value. This does not validate the length of a + postal code supplied directly in `postal_code`. + """ + payment_method: str """Default payment method for payments processed by this tool.""" + postal_code: Union[str, bool] + """Controls billing postal code collection for credit-card payments. + + Set to `false` to skip the postal code prompt without supplying a postal code to + the payment connector (non-US cards, e.g. Irish Eircodes). Set to `true` to + prompt the caller. Supply a non-empty string, such as `"90210"`, to use that + postal code without prompting. This option does not affect ACH debit payments or + payments using an existing token. + """ + + prompts: Prompts + """Custom text-to-speech prompts keyed by payment collection step. + + The AI assistant merges its own card-number prompt into this map, matching on + the same step keys. + """ + + timeout_millis: int + """Time in milliseconds to wait for DTMF input for each collection step. + + Omitted means the platform default (5000) applies. Increase this for slower + entry, e.g. a 16-digit card number. + """ + valid_card_types: List[ Literal["visa", "mastercard", "amex", "maestro", "discover", "optima", "jcb", "diners-club", "enroute"] ] diff --git a/src/telnyx/types/ai/privacy_settings.py b/src/telnyx/types/ai/privacy_settings.py index 4133115e9..57fd8d454 100644 --- a/src/telnyx/types/ai/privacy_settings.py +++ b/src/telnyx/types/ai/privacy_settings.py @@ -23,18 +23,26 @@ class PrivacySettings(BaseModel): in_transit_data_locality: Optional[bool] = None """ - Requires every model call made for a web chat turn to be received and served - inside your organization's data-locality region, rather than only stored there. - Applies to web chat only — voice and messaging assistants are unaffected. - Enabling it requires a data-locality region with in-region inference (USA, EU, - AUS, UAE; see - [Inference regions](https://developers.telnyx.com/docs/inference/models/regions)) - and Telnyx-hosted models for the assistant, its fallback, and any - conversation-flow node that overrides the model; the request is rejected - otherwise. Once enabled, send chat requests to your region's API hostname: a - request entering the platform in another region is rejected rather than - forwarded, because forwarding it would already have moved the content across the - border. Defaults to false. + Requires this assistant's conversations to be processed inside your + organization's data-locality region, rather than only stored there, on every + channel: for web chat, every model call of a turn; for voice, the call's model + calls and the Telnyx-hosted speech services it uses; for SMS and WhatsApp, the + model calls of each turn (how messages travel through carriers is not covered). + Covered processing that cannot be handled in region fails rather than being + served elsewhere. Enabling it requires a data-locality region with in-region + inference (USA, EU, AUS, UAE; see + [Inference regions](https://developers.telnyx.com/docs/inference/models/regions)), + Telnyx-hosted models for the assistant, its fallback, and any conversation-flow + node that overrides the model, and, when `insight_settings.model` is set, an + insight model available in that region; the request is rejected otherwise. A + voice call fails when it starts if its STT model or TTS voice is not self-hosted + by Telnyx, if the assistant uses a speech-to-speech model, or if the call's + media is anchored outside the region. Once enabled, send web chat requests and + WebSocket or WebRTC conversations to your region's API hostname: one entering + the platform in another region is refused rather than forwarded, because + forwarding it would already have moved the content across the border. See + [Data residency](https://developers.telnyx.com/docs/inference/data-residency#in-region-processing-for-ai-assistants). + Defaults to false. """ pii_redaction: Optional[Literal["disabled", "redact"]] = None diff --git a/src/telnyx/types/ai/privacy_settings_param.py b/src/telnyx/types/ai/privacy_settings_param.py index fc7740d9e..062a2ae0d 100644 --- a/src/telnyx/types/ai/privacy_settings_param.py +++ b/src/telnyx/types/ai/privacy_settings_param.py @@ -20,18 +20,26 @@ class PrivacySettingsParam(TypedDict, total=False): in_transit_data_locality: bool """ - Requires every model call made for a web chat turn to be received and served - inside your organization's data-locality region, rather than only stored there. - Applies to web chat only — voice and messaging assistants are unaffected. - Enabling it requires a data-locality region with in-region inference (USA, EU, - AUS, UAE; see - [Inference regions](https://developers.telnyx.com/docs/inference/models/regions)) - and Telnyx-hosted models for the assistant, its fallback, and any - conversation-flow node that overrides the model; the request is rejected - otherwise. Once enabled, send chat requests to your region's API hostname: a - request entering the platform in another region is rejected rather than - forwarded, because forwarding it would already have moved the content across the - border. Defaults to false. + Requires this assistant's conversations to be processed inside your + organization's data-locality region, rather than only stored there, on every + channel: for web chat, every model call of a turn; for voice, the call's model + calls and the Telnyx-hosted speech services it uses; for SMS and WhatsApp, the + model calls of each turn (how messages travel through carriers is not covered). + Covered processing that cannot be handled in region fails rather than being + served elsewhere. Enabling it requires a data-locality region with in-region + inference (USA, EU, AUS, UAE; see + [Inference regions](https://developers.telnyx.com/docs/inference/models/regions)), + Telnyx-hosted models for the assistant, its fallback, and any conversation-flow + node that overrides the model, and, when `insight_settings.model` is set, an + insight model available in that region; the request is rejected otherwise. A + voice call fails when it starts if its STT model or TTS voice is not self-hosted + by Telnyx, if the assistant uses a speech-to-speech model, or if the call's + media is anchored outside the region. Once enabled, send web chat requests and + WebSocket or WebRTC conversations to your region's API hostname: one entering + the platform in another region is refused rather than forwarded, because + forwarding it would already have moved the content across the border. See + [Data residency](https://developers.telnyx.com/docs/inference/data-residency#in-region-processing-for-ai-assistants). + Defaults to false. """ pii_redaction: Literal["disabled", "redact"] diff --git a/src/telnyx/types/ai/telephony_settings.py b/src/telnyx/types/ai/telephony_settings.py index 978c2cbc9..aad2e71ac 100644 --- a/src/telnyx/types/ai/telephony_settings.py +++ b/src/telnyx/types/ai/telephony_settings.py @@ -163,6 +163,15 @@ class TelephonySettings(BaseModel): bridged the call. """ + greeting_delay_ms: Optional[int] = None + """ + Milliseconds to wait after an inbound call is answered before the assistant + starts and speaks its greeting. Increase it if the beginning of the greeting is + cut off on some connections (for example, WebRTC calls). When unset (`null`), + the platform default of 250 ms is used. Set to `0` to start without a delay. + Maximum 2000. + """ + noise_suppression: Optional[Literal["aicoustics", "krisp", "deepfilternet", "disabled"]] = None """The noise suppression engine to use. diff --git a/src/telnyx/types/ai/telephony_settings_param.py b/src/telnyx/types/ai/telephony_settings_param.py index 6d6dd604a..d7181e39a 100644 --- a/src/telnyx/types/ai/telephony_settings_param.py +++ b/src/telnyx/types/ai/telephony_settings_param.py @@ -2,6 +2,7 @@ from __future__ import annotations +from typing import Optional from typing_extensions import Literal, TypedDict __all__ = [ @@ -160,6 +161,15 @@ class TelephonySettingsParam(TypedDict, total=False): bridged the call. """ + greeting_delay_ms: Optional[int] + """ + Milliseconds to wait after an inbound call is answered before the assistant + starts and speaks its greeting. Increase it if the beginning of the greeting is + cut off on some connections (for example, WebRTC calls). When unset (`null`), + the platform default of 250 ms is used. Set to `0` to start without a delay. + Maximum 2000. + """ + noise_suppression: Literal["aicoustics", "krisp", "deepfilternet", "disabled"] """The noise suppression engine to use. diff --git a/src/telnyx/types/ai/tests/test_framework/v1_retrieve_personalities_response.py b/src/telnyx/types/ai/tests/test_framework/v1_retrieve_personalities_response.py index cc3d8c757..e2aebcc04 100644 --- a/src/telnyx/types/ai/tests/test_framework/v1_retrieve_personalities_response.py +++ b/src/telnyx/types/ai/tests/test_framework/v1_retrieve_personalities_response.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import List, Union, Optional +from typing import Dict, List, Union, Optional from typing_extensions import TypeAlias from ....._models import BaseModel @@ -35,15 +35,15 @@ class V1RetrievePersonalitiesResponseItem(BaseModel): forked_from: Optional[int] = None """ID of the personality this one was forked from.""" - generation_config: Optional[object] = None + generation_config: Optional[Dict[str, object]] = None interruption_level: Optional[str] = None """How aggressively the personality interrupts the assistant.""" - message_plan: Optional[object] = None + message_plan: Optional[Dict[str, object]] = None """Idle-timeout plan for messages during a call.""" - network_simulation: Optional[object] = None + network_simulation: Optional[Dict[str, object]] = None organization: Optional[int] = None @@ -51,9 +51,9 @@ class V1RetrievePersonalitiesResponseItem(BaseModel): speed: Union[float, str, None] = None - start_speaking_plan: Union[float, object, None] = None + start_speaking_plan: Union[float, Dict[str, object], None] = None - stop_speaking_plan: Optional[object] = None + stop_speaking_plan: Optional[Dict[str, object]] = None voice_volume: Optional[float] = None diff --git a/src/telnyx/types/ai/transcription_challenger.py b/src/telnyx/types/ai/transcription_challenger.py new file mode 100644 index 000000000..1a5880c8d --- /dev/null +++ b/src/telnyx/types/ai/transcription_challenger.py @@ -0,0 +1,91 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Literal + +from ..._models import BaseModel +from .transcription_settings_config import TranscriptionSettingsConfig + +__all__ = ["TranscriptionChallenger"] + + +class TranscriptionChallenger(BaseModel): + """ + A second speech-to-text model that transcribes alongside `transcription.model`, and the rule that decides which transcript the assistant uses. + """ + + model: Literal[ + "deepgram/flux", + "deepgram/nova-3", + "deepgram/nova-2", + "azure/fast", + "assemblyai/universal-3-6-pro", + "assemblyai/universal-3-5-pro", + "assemblyai/universal-streaming", + "xai/grok-stt", + "soniox/stt-rt-v4", + "soniox/stt-rt-v5", + "nvidia/parakeet-v3", + "omi-health/omi-med-stt-v1", + "humain/realtime", + "reson8/turns", + "cohere/ar-stt", + "telnyx/basira", + "distil-whisper/distil-large-v2", + "openai/whisper-large-v3-turbo", + ] + """The language booster's model. + + It must be the same kind of model as `transcription.model`: both streaming + (`deepgram/flux`, `deepgram/nova-3`, `deepgram/nova-2`, + `assemblyai/universal-3-6-pro` or its legacy aliases + `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming`, + `xai/grok-stt`, `soniox/stt-rt-v4`, `soniox/stt-rt-v5`, `humain/realtime`, + `reson8/turns`) or both non-streaming (`azure/fast`, `nvidia/parakeet-v3`, + `omi-health/omi-med-stt-v1`, `cohere/ar-stt`, `distil-whisper/distil-large-v2`, + `openai/whisper-large-v3-turbo`, `telnyx/basira`). It can be the same model as + `transcription.model` on a different `language`. + """ + + language: Optional[str] = None + """The language this model transcribes. + + Omit it or set it to `null` to use the language of `transcription.model`. The + request is rejected when this model doesn't support the language it would run. + It is also rejected when it would run the same model on the same language as + `transcription.model`. + """ + + rule: Optional[Literal["best_turn", "best_engine", "merge_words"]] = None + """How the assistant picks the transcript it uses. + + The models are compared on how complete and confident their transcripts are, not + on language, so the rules work best when both models understand the callers' + language. + + - `best_turn` (default): both models transcribe the whole call. Each turn uses + the language booster's transcript only when it scores higher than the + transcript of `transcription.model` (clearly higher with non-streaming + models). With streaming models, `transcription.model` also decides when each + turn ends. Available for every pair. + - `best_engine`: both models transcribe the first turns, then the call continues + alone on the model whose transcripts scored higher. If neither clearly leads, + `transcription.model` continues. Streaming models only. + - `merge_words`: both models transcribe each utterance and their words are + merged, keeping Arabic and English spoken in the same sentence. Available only + for `telnyx/basira` with `cohere/ar-stt`, in either order. The pair runs on + the language that applies to `telnyx/basira` (its own, or that of + `transcription.model`), which must be Arabic (`ar` or an `ar-` locale), + `multi`, or `auto`. + """ + + settings: Optional[TranscriptionSettingsConfig] = None + """ + Settings for the language booster, with the same fields and limits as + `transcription.settings`. Fields that don't apply to this model's provider are + dropped, and the provider's defaults fill in the rest. Omit it or set it to + `null` to use the settings of `transcription.model` where they apply to this + model. + """ diff --git a/src/telnyx/types/ai/transcription_challenger_param.py b/src/telnyx/types/ai/transcription_challenger_param.py new file mode 100644 index 000000000..6cbbab0cc --- /dev/null +++ b/src/telnyx/types/ai/transcription_challenger_param.py @@ -0,0 +1,93 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["TranscriptionChallengerParam"] + + +class TranscriptionChallengerParam(TypedDict, total=False): + """ + A second speech-to-text model that transcribes alongside `transcription.model`, and the rule that decides which transcript the assistant uses. + """ + + model: Required[ + Literal[ + "deepgram/flux", + "deepgram/nova-3", + "deepgram/nova-2", + "azure/fast", + "assemblyai/universal-3-6-pro", + "assemblyai/universal-3-5-pro", + "assemblyai/universal-streaming", + "xai/grok-stt", + "soniox/stt-rt-v4", + "soniox/stt-rt-v5", + "nvidia/parakeet-v3", + "omi-health/omi-med-stt-v1", + "humain/realtime", + "reson8/turns", + "cohere/ar-stt", + "telnyx/basira", + "distil-whisper/distil-large-v2", + "openai/whisper-large-v3-turbo", + ] + ] + """The language booster's model. + + It must be the same kind of model as `transcription.model`: both streaming + (`deepgram/flux`, `deepgram/nova-3`, `deepgram/nova-2`, + `assemblyai/universal-3-6-pro` or its legacy aliases + `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming`, + `xai/grok-stt`, `soniox/stt-rt-v4`, `soniox/stt-rt-v5`, `humain/realtime`, + `reson8/turns`) or both non-streaming (`azure/fast`, `nvidia/parakeet-v3`, + `omi-health/omi-med-stt-v1`, `cohere/ar-stt`, `distil-whisper/distil-large-v2`, + `openai/whisper-large-v3-turbo`, `telnyx/basira`). It can be the same model as + `transcription.model` on a different `language`. + """ + + language: Optional[str] + """The language this model transcribes. + + Omit it or set it to `null` to use the language of `transcription.model`. The + request is rejected when this model doesn't support the language it would run. + It is also rejected when it would run the same model on the same language as + `transcription.model`. + """ + + rule: Literal["best_turn", "best_engine", "merge_words"] + """How the assistant picks the transcript it uses. + + The models are compared on how complete and confident their transcripts are, not + on language, so the rules work best when both models understand the callers' + language. + + - `best_turn` (default): both models transcribe the whole call. Each turn uses + the language booster's transcript only when it scores higher than the + transcript of `transcription.model` (clearly higher with non-streaming + models). With streaming models, `transcription.model` also decides when each + turn ends. Available for every pair. + - `best_engine`: both models transcribe the first turns, then the call continues + alone on the model whose transcripts scored higher. If neither clearly leads, + `transcription.model` continues. Streaming models only. + - `merge_words`: both models transcribe each utterance and their words are + merged, keeping Arabic and English spoken in the same sentence. Available only + for `telnyx/basira` with `cohere/ar-stt`, in either order. The pair runs on + the language that applies to `telnyx/basira` (its own, or that of + `transcription.model`), which must be Arabic (`ar` or an `ar-` locale), + `multi`, or `auto`. + """ + + settings: Optional["TranscriptionSettingsConfigParam"] + """ + Settings for the language booster, with the same fields and limits as + `transcription.settings`. Fields that don't apply to this model's provider are + dropped, and the provider's defaults fill in the rest. Omit it or set it to + `null` to use the settings of `transcription.model` where they apply to this + model. + """ + + +from .transcription_settings_config_param import TranscriptionSettingsConfigParam diff --git a/src/telnyx/types/ai/transcription_fallback_model.py b/src/telnyx/types/ai/transcription_fallback_model.py new file mode 100644 index 000000000..714b391b2 --- /dev/null +++ b/src/telnyx/types/ai/transcription_fallback_model.py @@ -0,0 +1,57 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Literal + +from ..._models import BaseModel +from .transcription_settings_config import TranscriptionSettingsConfig + +__all__ = ["TranscriptionFallbackModel"] + + +class TranscriptionFallbackModel(BaseModel): + """ + A streaming speech-to-text model that takes over transcription when the model in use fails. + """ + + model: Literal[ + "deepgram/flux", + "deepgram/nova-3", + "deepgram/nova-2", + "assemblyai/universal-3-6-pro", + "assemblyai/universal-3-5-pro", + "assemblyai/universal-streaming", + "xai/grok-stt", + "soniox/stt-rt-v4", + "soniox/stt-rt-v5", + "humain/realtime", + "reson8/turns", + ] + """The fallback model. + + It must be a streaming model other than `transcription.model` and the other + fallbacks: `deepgram/flux`, `deepgram/nova-3`, `deepgram/nova-2`, + `assemblyai/universal-3-6-pro` (or its legacy aliases + `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming`), + `xai/grok-stt`, `soniox/stt-rt-v4`, `soniox/stt-rt-v5`, `humain/realtime`, or + `reson8/turns`. + """ + + language: Optional[str] = None + """The language the fallback transcribes. + + Omit it or set it to `null` to use the language of `transcription.model`. The + request is rejected when the fallback model doesn't support the language it + would run. + """ + + settings: Optional[TranscriptionSettingsConfig] = None + """ + Settings for the fallback, with the same fields and limits as + `transcription.settings`. Fields that don't apply to this model's provider are + dropped, and the provider's defaults fill in the rest. Omit it or set it to + `null` to use the settings of `transcription.model` where they apply to this + model. + """ diff --git a/src/telnyx/types/ai/transcription_fallback_model_param.py b/src/telnyx/types/ai/transcription_fallback_model_param.py new file mode 100644 index 000000000..8bfe598a3 --- /dev/null +++ b/src/telnyx/types/ai/transcription_fallback_model_param.py @@ -0,0 +1,59 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["TranscriptionFallbackModelParam"] + + +class TranscriptionFallbackModelParam(TypedDict, total=False): + """ + A streaming speech-to-text model that takes over transcription when the model in use fails. + """ + + model: Required[ + Literal[ + "deepgram/flux", + "deepgram/nova-3", + "deepgram/nova-2", + "assemblyai/universal-3-6-pro", + "assemblyai/universal-3-5-pro", + "assemblyai/universal-streaming", + "xai/grok-stt", + "soniox/stt-rt-v4", + "soniox/stt-rt-v5", + "humain/realtime", + "reson8/turns", + ] + ] + """The fallback model. + + It must be a streaming model other than `transcription.model` and the other + fallbacks: `deepgram/flux`, `deepgram/nova-3`, `deepgram/nova-2`, + `assemblyai/universal-3-6-pro` (or its legacy aliases + `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming`), + `xai/grok-stt`, `soniox/stt-rt-v4`, `soniox/stt-rt-v5`, `humain/realtime`, or + `reson8/turns`. + """ + + language: Optional[str] + """The language the fallback transcribes. + + Omit it or set it to `null` to use the language of `transcription.model`. The + request is rejected when the fallback model doesn't support the language it + would run. + """ + + settings: Optional["TranscriptionSettingsConfigParam"] + """ + Settings for the fallback, with the same fields and limits as + `transcription.settings`. Fields that don't apply to this model's provider are + dropped, and the provider's defaults fill in the rest. Omit it or set it to + `null` to use the settings of `transcription.model` where they apply to this + model. + """ + + +from .transcription_settings_config_param import TranscriptionSettingsConfigParam diff --git a/src/telnyx/types/ai/transcription_settings.py b/src/telnyx/types/ai/transcription_settings.py index 1e329d047..ec18efffa 100644 --- a/src/telnyx/types/ai/transcription_settings.py +++ b/src/telnyx/types/ai/transcription_settings.py @@ -6,135 +6,11 @@ from typing_extensions import Literal from ..._models import BaseModel +from .transcription_challenger import TranscriptionChallenger +from .transcription_fallback_model import TranscriptionFallbackModel from .transcription_settings_config import TranscriptionSettingsConfig -__all__ = ["TranscriptionSettings", "Challenger", "FallbackModel"] - - -class Challenger(BaseModel): - """ - A second speech-to-text model that transcribes alongside `transcription.model`, and the rule that decides which transcript the assistant uses. - """ - - model: Literal[ - "deepgram/flux", - "deepgram/nova-3", - "deepgram/nova-2", - "azure/fast", - "assemblyai/universal-3-6-pro", - "assemblyai/universal-3-5-pro", - "assemblyai/universal-streaming", - "xai/grok-stt", - "soniox/stt-rt-v4", - "soniox/stt-rt-v5", - "nvidia/parakeet-v3", - "omi-health/omi-med-stt-v1", - "humain/realtime", - "reson8/turns", - "cohere/ar-stt", - "telnyx/basira", - "distil-whisper/distil-large-v2", - "openai/whisper-large-v3-turbo", - ] - """The language booster's model. - - It must be the same kind of model as `transcription.model`: both streaming - (`deepgram/flux`, `deepgram/nova-3`, `deepgram/nova-2`, - `assemblyai/universal-3-6-pro` or its legacy aliases - `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming`, - `xai/grok-stt`, `soniox/stt-rt-v4`, `soniox/stt-rt-v5`, `humain/realtime`, - `reson8/turns`) or both non-streaming (`azure/fast`, `nvidia/parakeet-v3`, - `omi-health/omi-med-stt-v1`, `cohere/ar-stt`, `distil-whisper/distil-large-v2`, - `openai/whisper-large-v3-turbo`, `telnyx/basira`). It can be the same model as - `transcription.model` on a different `language`. - """ - - language: Optional[str] = None - """The language this model transcribes. - - Omit it or set it to `null` to use the language of `transcription.model`. The - request is rejected when this model doesn't support the language it would run. - It is also rejected when it would run the same model on the same language as - `transcription.model`. - """ - - rule: Optional[Literal["best_turn", "best_engine", "merge_words"]] = None - """How the assistant picks the transcript it uses. - - The models are compared on how complete and confident their transcripts are, not - on language, so the rules work best when both models understand the callers' - language. - - - `best_turn` (default): both models transcribe the whole call. Each turn uses - the language booster's transcript only when it scores higher than the - transcript of `transcription.model` (clearly higher with non-streaming - models). With streaming models, `transcription.model` also decides when each - turn ends. Available for every pair. - - `best_engine`: both models transcribe the first turns, then the call continues - alone on the model whose transcripts scored higher. If neither clearly leads, - `transcription.model` continues. Streaming models only. - - `merge_words`: both models transcribe each utterance and their words are - merged, keeping Arabic and English spoken in the same sentence. Available only - for `telnyx/basira` with `cohere/ar-stt`, in either order. The pair runs on - the language that applies to `telnyx/basira` (its own, or that of - `transcription.model`), which must be Arabic (`ar` or an `ar-` locale), - `multi`, or `auto`. - """ - - settings: Optional[TranscriptionSettingsConfig] = None - """ - Settings for the language booster, with the same fields and limits as - `transcription.settings`. Fields that don't apply to this model's provider are - dropped, and the provider's defaults fill in the rest. Omit it or set it to - `null` to use the settings of `transcription.model` where they apply to this - model. - """ - - -class FallbackModel(BaseModel): - """ - A streaming speech-to-text model that takes over transcription when the model in use fails. - """ - - model: Literal[ - "deepgram/flux", - "deepgram/nova-3", - "deepgram/nova-2", - "assemblyai/universal-3-6-pro", - "assemblyai/universal-3-5-pro", - "assemblyai/universal-streaming", - "xai/grok-stt", - "soniox/stt-rt-v4", - "soniox/stt-rt-v5", - "humain/realtime", - "reson8/turns", - ] - """The fallback model. - - It must be a streaming model other than `transcription.model` and the other - fallbacks: `deepgram/flux`, `deepgram/nova-3`, `deepgram/nova-2`, - `assemblyai/universal-3-6-pro` (or its legacy aliases - `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming`), - `xai/grok-stt`, `soniox/stt-rt-v4`, `soniox/stt-rt-v5`, `humain/realtime`, or - `reson8/turns`. - """ - - language: Optional[str] = None - """The language the fallback transcribes. - - Omit it or set it to `null` to use the language of `transcription.model`. The - request is rejected when the fallback model doesn't support the language it - would run. - """ - - settings: Optional[TranscriptionSettingsConfig] = None - """ - Settings for the fallback, with the same fields and limits as - `transcription.settings`. Fields that don't apply to this model's provider are - dropped, and the provider's defaults fill in the rest. Omit it or set it to - `null` to use the settings of `transcription.model` where they apply to this - model. - """ +__all__ = ["TranscriptionSettings"] class TranscriptionSettings(BaseModel): @@ -145,13 +21,13 @@ class TranscriptionSettings(BaseModel): API key. """ - challenger: Optional[Challenger] = None + challenger: Optional[TranscriptionChallenger] = None """ A second speech-to-text model that transcribes alongside `transcription.model`, and the rule that decides which transcript the assistant uses. """ - fallback_models: Optional[List[FallbackModel]] = None + fallback_models: Optional[List[TranscriptionFallbackModel]] = None """ Up to 3 streaming models that take over transcription, in this order, when the model in use fails, at the start of a call or mid-call. `model` must be a diff --git a/src/telnyx/types/ai/transcription_settings_param.py b/src/telnyx/types/ai/transcription_settings_param.py index 899ff0d42..b22cdd15f 100644 --- a/src/telnyx/types/ai/transcription_settings_param.py +++ b/src/telnyx/types/ai/transcription_settings_param.py @@ -3,139 +3,9 @@ from __future__ import annotations from typing import Iterable, Optional -from typing_extensions import Literal, Required, TypedDict +from typing_extensions import Literal, TypedDict -__all__ = ["TranscriptionSettingsParam", "Challenger", "FallbackModel"] - - -class Challenger(TypedDict, total=False): - """ - A second speech-to-text model that transcribes alongside `transcription.model`, and the rule that decides which transcript the assistant uses. - """ - - model: Required[ - Literal[ - "deepgram/flux", - "deepgram/nova-3", - "deepgram/nova-2", - "azure/fast", - "assemblyai/universal-3-6-pro", - "assemblyai/universal-3-5-pro", - "assemblyai/universal-streaming", - "xai/grok-stt", - "soniox/stt-rt-v4", - "soniox/stt-rt-v5", - "nvidia/parakeet-v3", - "omi-health/omi-med-stt-v1", - "humain/realtime", - "reson8/turns", - "cohere/ar-stt", - "telnyx/basira", - "distil-whisper/distil-large-v2", - "openai/whisper-large-v3-turbo", - ] - ] - """The language booster's model. - - It must be the same kind of model as `transcription.model`: both streaming - (`deepgram/flux`, `deepgram/nova-3`, `deepgram/nova-2`, - `assemblyai/universal-3-6-pro` or its legacy aliases - `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming`, - `xai/grok-stt`, `soniox/stt-rt-v4`, `soniox/stt-rt-v5`, `humain/realtime`, - `reson8/turns`) or both non-streaming (`azure/fast`, `nvidia/parakeet-v3`, - `omi-health/omi-med-stt-v1`, `cohere/ar-stt`, `distil-whisper/distil-large-v2`, - `openai/whisper-large-v3-turbo`, `telnyx/basira`). It can be the same model as - `transcription.model` on a different `language`. - """ - - language: Optional[str] - """The language this model transcribes. - - Omit it or set it to `null` to use the language of `transcription.model`. The - request is rejected when this model doesn't support the language it would run. - It is also rejected when it would run the same model on the same language as - `transcription.model`. - """ - - rule: Literal["best_turn", "best_engine", "merge_words"] - """How the assistant picks the transcript it uses. - - The models are compared on how complete and confident their transcripts are, not - on language, so the rules work best when both models understand the callers' - language. - - - `best_turn` (default): both models transcribe the whole call. Each turn uses - the language booster's transcript only when it scores higher than the - transcript of `transcription.model` (clearly higher with non-streaming - models). With streaming models, `transcription.model` also decides when each - turn ends. Available for every pair. - - `best_engine`: both models transcribe the first turns, then the call continues - alone on the model whose transcripts scored higher. If neither clearly leads, - `transcription.model` continues. Streaming models only. - - `merge_words`: both models transcribe each utterance and their words are - merged, keeping Arabic and English spoken in the same sentence. Available only - for `telnyx/basira` with `cohere/ar-stt`, in either order. The pair runs on - the language that applies to `telnyx/basira` (its own, or that of - `transcription.model`), which must be Arabic (`ar` or an `ar-` locale), - `multi`, or `auto`. - """ - - settings: Optional["TranscriptionSettingsConfigParam"] - """ - Settings for the language booster, with the same fields and limits as - `transcription.settings`. Fields that don't apply to this model's provider are - dropped, and the provider's defaults fill in the rest. Omit it or set it to - `null` to use the settings of `transcription.model` where they apply to this - model. - """ - - -class FallbackModel(TypedDict, total=False): - """ - A streaming speech-to-text model that takes over transcription when the model in use fails. - """ - - model: Required[ - Literal[ - "deepgram/flux", - "deepgram/nova-3", - "deepgram/nova-2", - "assemblyai/universal-3-6-pro", - "assemblyai/universal-3-5-pro", - "assemblyai/universal-streaming", - "xai/grok-stt", - "soniox/stt-rt-v4", - "soniox/stt-rt-v5", - "humain/realtime", - "reson8/turns", - ] - ] - """The fallback model. - - It must be a streaming model other than `transcription.model` and the other - fallbacks: `deepgram/flux`, `deepgram/nova-3`, `deepgram/nova-2`, - `assemblyai/universal-3-6-pro` (or its legacy aliases - `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming`), - `xai/grok-stt`, `soniox/stt-rt-v4`, `soniox/stt-rt-v5`, `humain/realtime`, or - `reson8/turns`. - """ - - language: Optional[str] - """The language the fallback transcribes. - - Omit it or set it to `null` to use the language of `transcription.model`. The - request is rejected when the fallback model doesn't support the language it - would run. - """ - - settings: Optional["TranscriptionSettingsConfigParam"] - """ - Settings for the fallback, with the same fields and limits as - `transcription.settings`. Fields that don't apply to this model's provider are - dropped, and the provider's defaults fill in the rest. Omit it or set it to - `null` to use the settings of `transcription.model` where they apply to this - model. - """ +__all__ = ["TranscriptionSettingsParam"] class TranscriptionSettingsParam(TypedDict, total=False): @@ -146,13 +16,13 @@ class TranscriptionSettingsParam(TypedDict, total=False): API key. """ - challenger: Optional[Challenger] + challenger: Optional["TranscriptionChallengerParam"] """ A second speech-to-text model that transcribes alongside `transcription.model`, and the rule that decides which transcript the assistant uses. """ - fallback_models: Optional[Iterable[FallbackModel]] + fallback_models: Optional[Iterable["TranscriptionFallbackModelParam"]] """ Up to 3 streaming models that take over transcription, in this order, when the model in use fails, at the start of a call or mid-call. `model` must be a @@ -256,4 +126,6 @@ class TranscriptionSettingsParam(TypedDict, total=False): settings: "TranscriptionSettingsConfigParam" +from .transcription_challenger_param import TranscriptionChallengerParam +from .transcription_fallback_model_param import TranscriptionFallbackModelParam from .transcription_settings_config_param import TranscriptionSettingsConfigParam diff --git a/src/telnyx/types/browser_session_create_params.py b/src/telnyx/types/browser_session_create_params.py index 6345e52fe..8b4ef203c 100644 --- a/src/telnyx/types/browser_session_create_params.py +++ b/src/telnyx/types/browser_session_create_params.py @@ -2,6 +2,7 @@ from __future__ import annotations +from typing import Dict from typing_extensions import Required, TypedDict from .._types import SequenceNotStr @@ -22,7 +23,7 @@ class BrowserSessionCreateParams(TypedDict, total=False): limits: Limits - metadata: object + metadata: Dict[str, object] """Arbitrary key-value metadata.""" diff --git a/src/telnyx/types/browser_sessions/action_create_params.py b/src/telnyx/types/browser_sessions/action_create_params.py index 8a21d85a9..36c8b3572 100644 --- a/src/telnyx/types/browser_sessions/action_create_params.py +++ b/src/telnyx/types/browser_sessions/action_create_params.py @@ -20,7 +20,7 @@ "WaitForActionConditionUnionMember0", "WaitForActionConditionUnionMember1", "WaitForActionConditionUnionMember2", - "WaitForActionConditionKind", + "WaitForActionConditionUnionMember3", "BatchAction", "BatchActionAction", ] @@ -230,7 +230,7 @@ class WaitForActionConditionUnionMember2(TypedDict, total=False): text: Required[str] -class WaitForActionConditionKind(TypedDict, total=False): +class WaitForActionConditionUnionMember3(TypedDict, total=False): kind: Required[Literal["dom_stable"]] @@ -238,7 +238,7 @@ class WaitForActionConditionKind(TypedDict, total=False): WaitForActionConditionUnionMember0, WaitForActionConditionUnionMember1, WaitForActionConditionUnionMember2, - WaitForActionConditionKind, + WaitForActionConditionUnionMember3, ] diff --git a/src/telnyx/types/browser_sessions/action_response.py b/src/telnyx/types/browser_sessions/action_response.py index 551c7cdb0..0d657fba5 100644 --- a/src/telnyx/types/browser_sessions/action_response.py +++ b/src/telnyx/types/browser_sessions/action_response.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import List, Optional +from typing import Dict, List, Optional from datetime import datetime from typing_extensions import Literal @@ -43,7 +43,7 @@ class ResultObservation(BaseModel): metadata. """ - refs: Optional[object] = None + refs: Optional[Dict[str, object]] = None title: Optional[str] = None @@ -65,7 +65,7 @@ class Result(BaseModel): action to obtain usable refs. """ - results: Optional[List[object]] = None + results: Optional[List[Dict[str, object]]] = None """Present only for batch actions.""" title: Optional[str] = None @@ -91,7 +91,7 @@ class ActionResponse(BaseModel): execution_lost error and retryable=true; that is not proof of safe re-execution. """ - request: object + request: Dict[str, object] """ Normalized request metadata; defaults may be materialized and fill values are redacted as {redacted: true, length: number}, including inside batch actions. diff --git a/src/telnyx/types/browser_sessions/wait_for_action_param.py b/src/telnyx/types/browser_sessions/wait_for_action_param.py index 4274ba9d3..1e0047170 100644 --- a/src/telnyx/types/browser_sessions/wait_for_action_param.py +++ b/src/telnyx/types/browser_sessions/wait_for_action_param.py @@ -11,7 +11,7 @@ "ConditionUnionMember0", "ConditionUnionMember1", "ConditionUnionMember2", - "ConditionKind", + "ConditionUnionMember3", ] @@ -35,11 +35,11 @@ class ConditionUnionMember2(TypedDict, total=False): text: Required[str] -class ConditionKind(TypedDict, total=False): +class ConditionUnionMember3(TypedDict, total=False): kind: Required[Literal["dom_stable"]] -Condition: TypeAlias = Union[ConditionUnionMember0, ConditionUnionMember1, ConditionUnionMember2, ConditionKind] +Condition: TypeAlias = Union[ConditionUnionMember0, ConditionUnionMember1, ConditionUnionMember2, ConditionUnionMember3] class WaitForActionParam(TypedDict, total=False): diff --git a/src/telnyx/types/compute/funcs/__init__.py b/src/telnyx/types/compute/funcs/__init__.py index 25b036650..776e80fac 100644 --- a/src/telnyx/types/compute/funcs/__init__.py +++ b/src/telnyx/types/compute/funcs/__init__.py @@ -7,10 +7,15 @@ from .export_create_params import ExportCreateParams as ExportCreateParams if TYPE_CHECKING: + from .func_log_export_config import FuncLogExportConfig as FuncLogExportConfig from .func_log_export_config_response import FuncLogExportConfigResponse as FuncLogExportConfigResponse def __getattr__(name: str) -> Any: + if name == "FuncLogExportConfig": + from .func_log_export_config import FuncLogExportConfig + + return FuncLogExportConfig if name == "FuncLogExportConfigResponse": from .func_log_export_config_response import FuncLogExportConfigResponse diff --git a/src/telnyx/types/compute/funcs/func_log_export_config.py b/src/telnyx/types/compute/funcs/func_log_export_config.py new file mode 100644 index 000000000..339aa6f48 --- /dev/null +++ b/src/telnyx/types/compute/funcs/func_log_export_config.py @@ -0,0 +1,42 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from datetime import datetime +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["FuncLogExportConfig"] + + +class FuncLogExportConfig(BaseModel): + """Metadata-only view of a function's log export destination. + + Header values are write-only (encrypted server-side) and never appear in any response. + """ + + id: Optional[str] = None + """Configuration record ID""" + + created_at: Optional[datetime] = None + + enabled: Optional[bool] = None + """Whether export is enabled for this function""" + + endpoint: Optional[str] = None + """HTTPS OTLP endpoint URL logs are pushed to""" + + func_id: Optional[str] = None + """Function ID this configuration belongs to""" + + invocation_export_enabled: Optional[bool] = None + """Whether invocation records (one per HTTP request) are exported""" + + record_type: Optional[Literal["compute_func_log_export_config"]] = None + + runtime_export_enabled: Optional[bool] = None + """Whether runtime logs (function stdout/stderr) are exported""" + + updated_at: Optional[datetime] = None diff --git a/src/telnyx/types/compute/funcs/func_log_export_config_response.py b/src/telnyx/types/compute/funcs/func_log_export_config_response.py index 6f766f3a6..9ec9d584a 100644 --- a/src/telnyx/types/compute/funcs/func_log_export_config_response.py +++ b/src/telnyx/types/compute/funcs/func_log_export_config_response.py @@ -3,47 +3,15 @@ from __future__ import annotations from typing import Optional -from datetime import datetime -from typing_extensions import Literal from ...._models import BaseModel +from .func_log_export_config import FuncLogExportConfig -__all__ = ["FuncLogExportConfigResponse", "Data"] - - -class Data(BaseModel): - """Metadata-only view of a function's log export destination. - - Header values are write-only (encrypted server-side) and never appear in any response. - """ - - id: Optional[str] = None - """Configuration record ID""" - - created_at: Optional[datetime] = None - - enabled: Optional[bool] = None - """Whether export is enabled for this function""" - - endpoint: Optional[str] = None - """HTTPS OTLP endpoint URL logs are pushed to""" - - func_id: Optional[str] = None - """Function ID this configuration belongs to""" - - invocation_export_enabled: Optional[bool] = None - """Whether invocation records (one per HTTP request) are exported""" - - record_type: Optional[Literal["compute_func_log_export_config"]] = None - - runtime_export_enabled: Optional[bool] = None - """Whether runtime logs (function stdout/stderr) are exported""" - - updated_at: Optional[datetime] = None +__all__ = ["FuncLogExportConfigResponse"] class FuncLogExportConfigResponse(BaseModel): - data: Optional[Data] = None + data: Optional[FuncLogExportConfig] = None """Metadata-only view of a function's log export destination. Header values are write-only (encrypted server-side) and never appear in any diff --git a/src/telnyx/types/email_event_list_response.py b/src/telnyx/types/email_event_list_response.py index 0690a160b..fb8ba5e09 100644 --- a/src/telnyx/types/email_event_list_response.py +++ b/src/telnyx/types/email_event_list_response.py @@ -2,33 +2,23 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Dict, List, Union, Optional +from typing import TYPE_CHECKING, Dict, Union, Optional from datetime import datetime from typing_extensions import Literal, TypeAlias from pydantic import Field as FieldInfo from .._models import BaseModel -from .time_range import TimeRange from .email_webhook_recipient import EmailWebhookRecipient -__all__ = [ - "EmailEventListResponse", - "Data", - "DataPayload", - "DataPayloadBcc", - "DataPayloadCc", - "DataPayloadFrom", - "DataPayloadTo", - "Meta", -] +__all__ = ["EmailEventListResponse", "Payload", "PayloadBcc", "PayloadCc", "PayloadFrom", "PayloadTo"] -DataPayloadBcc: TypeAlias = Union[EmailWebhookRecipient, Literal["redacted"]] +PayloadBcc: TypeAlias = Union[EmailWebhookRecipient, Literal["redacted"]] -DataPayloadCc: TypeAlias = Union[EmailWebhookRecipient, str] +PayloadCc: TypeAlias = Union[EmailWebhookRecipient, str] -class DataPayloadFrom(BaseModel): +class PayloadFrom(BaseModel): """Sender projection in account event polling. The display name is explicitly null when the message has no sender name. @@ -39,10 +29,10 @@ class DataPayloadFrom(BaseModel): name: Optional[str] = None -DataPayloadTo: TypeAlias = Union[EmailWebhookRecipient, str] +PayloadTo: TypeAlias = Union[EmailWebhookRecipient, str] -class DataPayload(BaseModel): +class Payload(BaseModel): """Payload returned by GET /email_events. Every row includes id, status, and occurred_at. Recipient-scoped rows also include recipient_id, from, subject, and exactly one object-valued to, cc, or bcc field. Legacy or message-scoped rows can omit recipient_id and use object-valued or string-valued to/cc fields, including an empty string when no address exists; bcc is redacted. If the related message or recipient cannot be loaded, the minimal fallback can omit from, subject, and recipient fields. Additional persisted public evidence can be present. @@ -90,12 +80,12 @@ class DataPayload(BaseModel): canonical_event_type to identify the outcome across surfaces. """ - bcc: Optional[DataPayloadBcc] = None + bcc: Optional[PayloadBcc] = None - cc: Optional[DataPayloadCc] = None + cc: Optional[PayloadCc] = None """Legacy message-scoped address, or an empty string when absent.""" - from_: Optional[DataPayloadFrom] = FieldInfo(alias="from", default=None) + from_: Optional[PayloadFrom] = FieldInfo(alias="from", default=None) """Sender projection in account event polling. The display name is explicitly null when the message has no sender name. @@ -106,7 +96,7 @@ class DataPayload(BaseModel): subject: Optional[str] = None - to: Optional[DataPayloadTo] = None + to: Optional[PayloadTo] = None """Legacy message-scoped address, or an empty string when absent.""" if TYPE_CHECKING: @@ -122,7 +112,7 @@ def __getattr__(self, attr: str) -> object: ... __pydantic_extra__: Dict[str, object] -class Data(BaseModel): +class EmailEventListResponse(BaseModel): """An account-polling event. The envelope is webhook-shaped, but polling preserves stored-event cardinality: queued, sending, sandbox, cancelled, and daily_limit_exceeded message events fan out per recipient; scheduled remains one message-scoped row. Payload fields vary among recipient-scoped, message-scoped, and minimal fallback rows. @@ -150,7 +140,7 @@ class Data(BaseModel): occurred_at: datetime - payload: DataPayload + payload: Payload """Payload returned by GET /email_events. Every row includes id, status, and occurred_at. Recipient-scoped rows also @@ -168,18 +158,3 @@ class Data(BaseModel): Present for recipient-scoped events, including each queued, sending, sandbox, cancelled, and daily_limit_exceeded fan-out event. """ - - -class Meta(BaseModel): - page_size: int - - time_range: TimeRange - - page_cursor: Optional[str] = None - """Cursor for the next page, when more results are available.""" - - -class EmailEventListResponse(BaseModel): - data: List[Data] - - meta: Meta diff --git a/src/telnyx/types/email_template_common.py b/src/telnyx/types/email_template_common.py index dbc98c1ec..0abfd6a5c 100644 --- a/src/telnyx/types/email_template_common.py +++ b/src/telnyx/types/email_template_common.py @@ -7,19 +7,9 @@ from typing_extensions import Literal from .._models import BaseModel +from .variable_schema_entry import VariableSchemaEntry -__all__ = ["EmailTemplateCommon", "VariableSchema"] - - -class VariableSchema(BaseModel): - required: bool - """ - Whether the variable must be supplied when strict variable validation is - enabled. - """ - - default: Optional[str] = None - """Default value for an optional variable. Rejected when `required` is `true`.""" +__all__ = ["EmailTemplateCommon"] class EmailTemplateCommon(BaseModel): @@ -51,7 +41,7 @@ class EmailTemplateCommon(BaseModel): updated_at: datetime - variable_schema: Optional[Dict[str, VariableSchema]] = None + variable_schema: Optional[Dict[str, VariableSchemaEntry]] = None """ Structured variable requirements, or `null` when the template uses only the legacy `variables` array. diff --git a/src/telnyx/types/email_template_create_params.py b/src/telnyx/types/email_template_create_params.py index bee2b6f98..6bee213fb 100644 --- a/src/telnyx/types/email_template_create_params.py +++ b/src/telnyx/types/email_template_create_params.py @@ -8,7 +8,7 @@ from .._types import SequenceNotStr from .._utils import PropertyInfo -__all__ = ["EmailTemplateCreateParams", "VariableSchema"] +__all__ = ["EmailTemplateCreateParams"] class EmailTemplateCreateParams(TypedDict, total=False): @@ -46,7 +46,7 @@ class EmailTemplateCreateParams(TypedDict, total=False): text_body: Optional[str] """Liquid template text body.""" - variable_schema: Optional[Dict[str, VariableSchema]] + variable_schema: Optional[Dict[str, "VariableSchemaEntryParam"]] """Structured variable requirements. Required variables cannot define defaults; invalid combinations return 422. This @@ -79,12 +79,4 @@ class EmailTemplateCreateParams(TypedDict, total=False): idempotency_key: Annotated[str, PropertyInfo(alias="Idempotency-Key")] -class VariableSchema(TypedDict, total=False): - required: Required[bool] - """ - Whether the variable must be supplied when strict variable validation is - enabled. - """ - - default: str - """Default value for an optional variable. Rejected when `required` is `true`.""" +from .variable_schema_entry_param import VariableSchemaEntryParam diff --git a/src/telnyx/types/email_template_replace_params.py b/src/telnyx/types/email_template_replace_params.py index a3fc20208..562222edb 100644 --- a/src/telnyx/types/email_template_replace_params.py +++ b/src/telnyx/types/email_template_replace_params.py @@ -3,11 +3,11 @@ from __future__ import annotations from typing import Dict, Optional -from typing_extensions import Literal, Required, TypedDict +from typing_extensions import Literal, TypedDict from .._types import SequenceNotStr -__all__ = ["EmailTemplateReplaceParams", "VariableSchema"] +__all__ = ["EmailTemplateReplaceParams"] class EmailTemplateReplaceParams(TypedDict, total=False): @@ -28,7 +28,7 @@ class EmailTemplateReplaceParams(TypedDict, total=False): text_body: Optional[str] """Liquid template text body.""" - variable_schema: Optional[Dict[str, VariableSchema]] + variable_schema: Optional[Dict[str, "VariableSchemaEntryParam"]] """Structured variable requirements. Required variables cannot define defaults; invalid combinations return 422. Set @@ -54,12 +54,4 @@ class EmailTemplateReplaceParams(TypedDict, total=False): """ -class VariableSchema(TypedDict, total=False): - required: Required[bool] - """ - Whether the variable must be supplied when strict variable validation is - enabled. - """ - - default: str - """Default value for an optional variable. Rejected when `required` is `true`.""" +from .variable_schema_entry_param import VariableSchemaEntryParam diff --git a/src/telnyx/types/email_template_update_params.py b/src/telnyx/types/email_template_update_params.py index bfc57be68..82ed9a640 100644 --- a/src/telnyx/types/email_template_update_params.py +++ b/src/telnyx/types/email_template_update_params.py @@ -3,11 +3,11 @@ from __future__ import annotations from typing import Dict, Optional -from typing_extensions import Literal, Required, TypedDict +from typing_extensions import Literal, TypedDict from .._types import SequenceNotStr -__all__ = ["EmailTemplateUpdateParams", "VariableSchema"] +__all__ = ["EmailTemplateUpdateParams"] class EmailTemplateUpdateParams(TypedDict, total=False): @@ -28,7 +28,7 @@ class EmailTemplateUpdateParams(TypedDict, total=False): text_body: Optional[str] """Liquid template text body.""" - variable_schema: Optional[Dict[str, VariableSchema]] + variable_schema: Optional[Dict[str, "VariableSchemaEntryParam"]] """Structured variable requirements. Required variables cannot define defaults; invalid combinations return 422. Set @@ -54,12 +54,4 @@ class EmailTemplateUpdateParams(TypedDict, total=False): """ -class VariableSchema(TypedDict, total=False): - required: Required[bool] - """ - Whether the variable must be supplied when strict variable validation is - enabled. - """ - - default: str - """Default value for an optional variable. Rejected when `required` is `true`.""" +from .variable_schema_entry_param import VariableSchemaEntryParam diff --git a/src/telnyx/types/enterprises/__init__.py b/src/telnyx/types/enterprises/__init__.py index e20dd2d95..672145877 100644 --- a/src/telnyx/types/enterprises/__init__.py +++ b/src/telnyx/types/enterprises/__init__.py @@ -14,6 +14,9 @@ if TYPE_CHECKING: from .enterprise_reputation_public import EnterpriseReputationPublic as EnterpriseReputationPublic + from .enterprise_email_verification_status import ( + EnterpriseEmailVerificationStatus as EnterpriseEmailVerificationStatus, + ) from .enterprise_reputation_public_wrapped import ( EnterpriseReputationPublicWrapped as EnterpriseReputationPublicWrapped, ) @@ -31,6 +34,10 @@ def __getattr__(name: str) -> Any: from .enterprise_reputation_public_wrapped import EnterpriseReputationPublicWrapped return EnterpriseReputationPublicWrapped + if name == "EnterpriseEmailVerificationStatus": + from .enterprise_email_verification_status import EnterpriseEmailVerificationStatus + + return EnterpriseEmailVerificationStatus if name == "EnterpriseEmailVerificationStatusWrapped": from .enterprise_email_verification_status_wrapped import EnterpriseEmailVerificationStatusWrapped diff --git a/src/telnyx/types/enterprises/enterprise_email_verification_status.py b/src/telnyx/types/enterprises/enterprise_email_verification_status.py new file mode 100644 index 000000000..272a33965 --- /dev/null +++ b/src/telnyx/types/enterprises/enterprise_email_verification_status.py @@ -0,0 +1,36 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from datetime import datetime +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["EnterpriseEmailVerificationStatus"] + + +class EnterpriseEmailVerificationStatus(BaseModel): + """Verification state for an enterprise account's contact email.""" + + email_verified: bool + """Whether the enterprise account's contact email has been confirmed.""" + + record_type: Literal["email_verification"] + """Always `email_verification`.""" + + status: Literal["sent", "verified"] + """`sent` after a code is emailed; `verified` after a successful confirm.""" + + expires_at: Optional[datetime] = None + """When the code just sent stops being accepted. + + Present on a send response; null on a confirm response. + """ + + sends_remaining_today: Optional[int] = None + """How many more codes may be requested for this enterprise account today. + + Present on a send response; null on a confirm response. + """ diff --git a/src/telnyx/types/enterprises/enterprise_email_verification_status_wrapped.py b/src/telnyx/types/enterprises/enterprise_email_verification_status_wrapped.py index 75c57ea2d..171d6246b 100644 --- a/src/telnyx/types/enterprises/enterprise_email_verification_status_wrapped.py +++ b/src/telnyx/types/enterprises/enterprise_email_verification_status_wrapped.py @@ -2,40 +2,12 @@ from __future__ import annotations -from typing import Optional -from datetime import datetime -from typing_extensions import Literal - from ..._models import BaseModel +from .enterprise_email_verification_status import EnterpriseEmailVerificationStatus -__all__ = ["EnterpriseEmailVerificationStatusWrapped", "Data"] - - -class Data(BaseModel): - """Verification state for an enterprise account's contact email.""" - - email_verified: bool - """Whether the enterprise account's contact email has been confirmed.""" - - record_type: Literal["email_verification"] - """Always `email_verification`.""" - - status: Literal["sent", "verified"] - """`sent` after a code is emailed; `verified` after a successful confirm.""" - - expires_at: Optional[datetime] = None - """When the code just sent stops being accepted. - - Present on a send response; null on a confirm response. - """ - - sends_remaining_today: Optional[int] = None - """How many more codes may be requested for this enterprise account today. - - Present on a send response; null on a confirm response. - """ +__all__ = ["EnterpriseEmailVerificationStatusWrapped"] class EnterpriseEmailVerificationStatusWrapped(BaseModel): - data: Data + data: EnterpriseEmailVerificationStatus """Verification state for an enterprise account's contact email.""" diff --git a/src/telnyx/types/enterprises/reputation/__init__.py b/src/telnyx/types/enterprises/reputation/__init__.py index 8567e6af6..af56fd994 100644 --- a/src/telnyx/types/enterprises/reputation/__init__.py +++ b/src/telnyx/types/enterprises/reputation/__init__.py @@ -22,6 +22,7 @@ if TYPE_CHECKING: from .remediation_request import RemediationRequest as RemediationRequest + from .external_verification import ExternalVerification as ExternalVerification from .number_refresh_response import NumberRefreshResponse as NumberRefreshResponse from .reputation_phone_number import ReputationPhoneNumber as ReputationPhoneNumber from .remediation_list_response import RemediationListResponse as RemediationListResponse @@ -72,6 +73,10 @@ def __getattr__(name: str) -> Any: from .remediation_list_response import RemediationListResponse return RemediationListResponse + if name == "ExternalVerification": + from .external_verification import ExternalVerification + + return ExternalVerification if name == "ExternalVerificationWrapped": from .external_verification_wrapped import ExternalVerificationWrapped diff --git a/src/telnyx/types/enterprises/reputation/external_verification.py b/src/telnyx/types/enterprises/reputation/external_verification.py new file mode 100644 index 000000000..53b766a27 --- /dev/null +++ b/src/telnyx/types/enterprises/reputation/external_verification.py @@ -0,0 +1,34 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import List, Optional +from datetime import datetime + +from ...._models import BaseModel +from .external_verification_status import ExternalVerificationStatus + +__all__ = ["ExternalVerification"] + + +class ExternalVerification(BaseModel): + document_ids: Optional[List[str]] = None + """The ownership-proof documents on file.""" + + enterprise_id: Optional[str] = None + + phone_numbers: Optional[List[str]] = None + """The phone numbers you listed with the documents.""" + + rejection_reason: Optional[str] = None + """Why the proof was rejected. Set only when `status` is `rejected`.""" + + reviewed_at: Optional[datetime] = None + + status: Optional[ExternalVerificationStatus] = None + """ + Review state of the ownership proof that allows adding phone numbers hosted with + another provider. + """ + + submitted_at: Optional[datetime] = None diff --git a/src/telnyx/types/enterprises/reputation/external_verification_wrapped.py b/src/telnyx/types/enterprises/reputation/external_verification_wrapped.py index cd7064f23..e0449e8ff 100644 --- a/src/telnyx/types/enterprises/reputation/external_verification_wrapped.py +++ b/src/telnyx/types/enterprises/reputation/external_verification_wrapped.py @@ -2,37 +2,11 @@ from __future__ import annotations -from typing import List, Optional -from datetime import datetime - from ...._models import BaseModel -from .external_verification_status import ExternalVerificationStatus - -__all__ = ["ExternalVerificationWrapped", "Data"] - - -class Data(BaseModel): - document_ids: Optional[List[str]] = None - """The ownership-proof documents on file.""" - - enterprise_id: Optional[str] = None - - phone_numbers: Optional[List[str]] = None - """The phone numbers you listed with the documents.""" - - rejection_reason: Optional[str] = None - """Why the proof was rejected. Set only when `status` is `rejected`.""" - - reviewed_at: Optional[datetime] = None - - status: Optional[ExternalVerificationStatus] = None - """ - Review state of the ownership proof that allows adding phone numbers hosted with - another provider. - """ +from .external_verification import ExternalVerification - submitted_at: Optional[datetime] = None +__all__ = ["ExternalVerificationWrapped"] class ExternalVerificationWrapped(BaseModel): - data: Data + data: ExternalVerification diff --git a/src/telnyx/types/generic_pay_connector_config_param.py b/src/telnyx/types/generic_pay_connector_config_param.py index ebd69ef24..263a36b65 100644 --- a/src/telnyx/types/generic_pay_connector_config_param.py +++ b/src/telnyx/types/generic_pay_connector_config_param.py @@ -20,7 +20,7 @@ class BasicAuthenticationAlsoTheValidationDefault(TypedDict, total=False): username: Required[str] """Basic username.""" - token: object + token: str """Nonblank string required for bearer authentication. Write-only; omitted from responses. Re-send when replacing a bearer-auth config. @@ -54,7 +54,7 @@ class BearerAuthentication(TypedDict, total=False): Use HTTPS to protect payment data in transit. """ - password: object + password: str """Nonblank string required for basic authentication. Write-only; omitted from responses. Re-send when replacing a basic-auth config. @@ -67,7 +67,7 @@ class BearerAuthentication(TypedDict, total=False): digit-gather timeout. """ - username: object + username: str """Nonblank string required for basic authentication. Returned in connector responses. @@ -77,7 +77,7 @@ class BearerAuthentication(TypedDict, total=False): class NoProcessorAuthentication(TypedDict, total=False): auth_type: Required[Literal["none"]] - token: object + token: str """Nonblank string required for bearer authentication. Write-only; omitted from responses. Re-send when replacing a bearer-auth config. @@ -89,7 +89,7 @@ class NoProcessorAuthentication(TypedDict, total=False): Use HTTPS to protect payment data in transit. """ - password: object + password: str """Nonblank string required for basic authentication. Write-only; omitted from responses. Re-send when replacing a basic-auth config. @@ -102,7 +102,7 @@ class NoProcessorAuthentication(TypedDict, total=False): digit-gather timeout. """ - username: object + username: str """Nonblank string required for basic authentication. Returned in connector responses. diff --git a/src/telnyx/types/message_whatsapp_params.py b/src/telnyx/types/message_whatsapp_params.py index e8174ded4..bb13861d6 100644 --- a/src/telnyx/types/message_whatsapp_params.py +++ b/src/telnyx/types/message_whatsapp_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Iterable +from typing import Dict, Iterable from typing_extensions import Literal, Required, Annotated, TypedDict from .._utils import PropertyInfo @@ -196,7 +196,7 @@ class WhatsappMessageInteractiveActionParametersFlowActionPayload(TypedDict, tot When omitted, the flow opens on its first entry screen. Must be omitted when flow_action is data_exchange """ - data: object + data: Dict[str, object] """input data for the first screen. Must be a non-empty object when provided""" screen: str @@ -338,7 +338,7 @@ class WhatsappMessageInteractive(TypedDict, total=False): class WhatsappMessageTemplateComponentParameterAction(TypedDict, total=False): """Flow button parameters. Used with type action on a flow button component""" - flow_action_data: object + flow_action_data: Dict[str, object] """input data for the first screen of the flow""" flow_token: str diff --git a/src/telnyx/types/messaging_profile_features.py b/src/telnyx/types/messaging_profile_features.py index 2e27c79da..459f487c3 100644 --- a/src/telnyx/types/messaging_profile_features.py +++ b/src/telnyx/types/messaging_profile_features.py @@ -24,6 +24,18 @@ class MessagingProfileFeatures(BaseModel): natural-language phrases) and treats them as opt-outs. """ + auto_chunk_long_messages: Optional[bool] = None + """Enables server-side chunking of outbound SMS. + + When enabled, an outbound message that exceeds the maximum number of segments + allowed for its destination (10 segments by default; some aggregators accept up + to 25) is automatically split into multiple child messages, each within the + segment limit, and sent sequentially in order. Splitting is encoding-aware: + GSM-7 bodies split at 153-character boundaries and UCS-2 bodies at 134-byte + (67-character) boundaries. When disabled (the default), messages exceeding the + segment limit are rejected with an error. + """ + 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. diff --git a/src/telnyx/types/messaging_profile_features_param.py b/src/telnyx/types/messaging_profile_features_param.py index 39cd7c236..5d5079bbd 100644 --- a/src/telnyx/types/messaging_profile_features_param.py +++ b/src/telnyx/types/messaging_profile_features_param.py @@ -19,3 +19,15 @@ class MessagingProfileFeaturesParam(TypedDict, total=False, extra_items=object): applies an AI model to identify non-standard opt-out requests (e.g. natural-language phrases) and treats them as opt-outs. """ + + auto_chunk_long_messages: bool + """Enables server-side chunking of outbound SMS. + + When enabled, an outbound message that exceeds the maximum number of segments + allowed for its destination (10 segments by default; some aggregators accept up + to 25) is automatically split into multiple child messages, each within the + segment limit, and sent sequentially in order. Splitting is encoding-aware: + GSM-7 bodies split at 153-character boundaries and UCS-2 bodies at 134-byte + (67-character) boundaries. When disabled (the default), messages exceeding the + segment limit are rejected with an error. + """ diff --git a/src/telnyx/types/model_metadata.py b/src/telnyx/types/model_metadata.py index e09d4ec0e..35e0aa65b 100644 --- a/src/telnyx/types/model_metadata.py +++ b/src/telnyx/types/model_metadata.py @@ -70,6 +70,13 @@ class ModelMetadata(BaseModel): Only set for fine-tuned models. """ + beta: Optional[bool] = None + """Whether the model is in beta. + + New Telnyx-hosted models launch with `beta: true`; the label is removed once the + model is established. + """ + description: Optional[str] = None """Short, human-readable summary of what the model is best suited for.""" diff --git a/src/telnyx/types/outbound_message_payload.py b/src/telnyx/types/outbound_message_payload.py index c7a640ecb..67f94c845 100644 --- a/src/telnyx/types/outbound_message_payload.py +++ b/src/telnyx/types/outbound_message_payload.py @@ -167,6 +167,13 @@ class OutboundMessagePayload(BaseModel): cc: Optional[List[Cc]] = None + child_message_id: Optional[str] = None + """ + Identifies the next chunk when server-side SMS chunking + (`auto_chunk_long_messages` on the messaging profile) split this message. Always + present; null on non-chunked messages and on the final chunk. + """ + completed_at: Optional[datetime] = None """ISO 8601 formatted date indicating when the message was finalized.""" @@ -203,6 +210,14 @@ class OutboundMessagePayload(BaseModel): organization_id: Optional[str] = None """The id of the organization the messaging profile belongs to.""" + parent_message_id: Optional[str] = None + """ + Identifies the original request's message when server-side SMS chunking + (`auto_chunk_long_messages` on the messaging profile) split it into chunks. The + first chunk's ID is the original request's message ID. Always present; null when + this message is not part of a chunked send. + """ + parts: Optional[int] = None """Number of parts into which the message's body must be split.""" diff --git a/src/telnyx/types/pay_connector.py b/src/telnyx/types/pay_connector.py index 3465f37da..7d981456f 100644 --- a/src/telnyx/types/pay_connector.py +++ b/src/telnyx/types/pay_connector.py @@ -35,7 +35,7 @@ class Config(BaseModel): Omitted when no timeout was configured; the effective runtime default is 10000. """ - username: Optional[object] = None + username: Optional[str] = None """Stored username, when supplied. Required to be a nonblank string for basic authentication. diff --git a/src/telnyx/types/phone_numbers/__init__.py b/src/telnyx/types/phone_numbers/__init__.py index 3dca1c0c4..c73e811fd 100644 --- a/src/telnyx/types/phone_numbers/__init__.py +++ b/src/telnyx/types/phone_numbers/__init__.py @@ -50,9 +50,13 @@ from .action_enable_emergency_response import ActionEnableEmergencyResponse as ActionEnableEmergencyResponse from .action_verify_ownership_response import ActionVerifyOwnershipResponse as ActionVerifyOwnershipResponse from .phone_number_with_voice_settings import PhoneNumberWithVoiceSettings as PhoneNumberWithVoiceSettings + from .phone_numbers_job_pending_operation import PhoneNumbersJobPendingOperation as PhoneNumbersJobPendingOperation from .action_change_bundle_status_response import ( ActionChangeBundleStatusResponse as ActionChangeBundleStatusResponse, ) + from .phone_numbers_job_successful_operation import ( + PhoneNumbersJobSuccessfulOperation as PhoneNumbersJobSuccessfulOperation, + ) from .job_update_emergency_settings_batch_response import ( JobUpdateEmergencySettingsBatchResponse as JobUpdateEmergencySettingsBatchResponse, ) @@ -91,6 +95,14 @@ def __getattr__(name: str) -> Any: from .numbers_phone_numbers_job import NumbersPhoneNumbersJob return NumbersPhoneNumbersJob + if name == "PhoneNumbersJobPendingOperation": + from .phone_numbers_job_pending_operation import PhoneNumbersJobPendingOperation + + return PhoneNumbersJobPendingOperation + if name == "PhoneNumbersJobSuccessfulOperation": + from .phone_numbers_job_successful_operation import PhoneNumbersJobSuccessfulOperation + + return PhoneNumbersJobSuccessfulOperation if name == "JobRetrieveResponse": from .job_retrieve_response import JobRetrieveResponse diff --git a/src/telnyx/types/phone_numbers/numbers_phone_numbers_job.py b/src/telnyx/types/phone_numbers/numbers_phone_numbers_job.py index 70c1e3fc5..94ae2d993 100644 --- a/src/telnyx/types/phone_numbers/numbers_phone_numbers_job.py +++ b/src/telnyx/types/phone_numbers/numbers_phone_numbers_job.py @@ -8,7 +8,9 @@ from ..._models import BaseModel from ..numbers_error_73c9788e53 import NumbersError73c9788e53 +from .phone_numbers_job_pending_operation import PhoneNumbersJobPendingOperation from ..shared.phone_numbers_job_phone_number import PhoneNumbersJobPhoneNumber +from .phone_numbers_job_successful_operation import PhoneNumbersJobSuccessfulOperation __all__ = [ "NumbersPhoneNumbersJob", @@ -19,8 +21,6 @@ "ParametersVoiceCallRecording", "ParametersVoiceCnamListing", "ParametersVoiceMediaFeatures", - "PendingOperation", - "SuccessfulOperation", ] @@ -168,29 +168,6 @@ class Parameters(BaseModel): """ -class PendingOperation(BaseModel): - """The phone numbers pending confirmation on update results. - - Entries in this list are transient, and will be moved to either successful_operations or failed_operations once the processing is done. - """ - - id: Optional[str] = None - """The phone number's ID""" - - phone_number: Optional[str] = None - """The phone number in e164 format.""" - - -class SuccessfulOperation(BaseModel): - """The phone numbers successfully updated.""" - - id: Optional[str] = None - """The phone number's ID""" - - phone_number: Optional[str] = None - """The phone number in e164 format.""" - - class NumbersPhoneNumbersJob(BaseModel): id: Optional[str] = None """Identifies the resource.""" @@ -217,7 +194,7 @@ class NumbersPhoneNumbersJob(BaseModel): filters. Historical jobs with no saved arguments return an empty object. """ - pending_operations: Optional[List[PendingOperation]] = None + pending_operations: Optional[List[PhoneNumbersJobPendingOperation]] = None phone_numbers: Optional[List[PhoneNumbersJobPhoneNumber]] = None @@ -227,7 +204,7 @@ class NumbersPhoneNumbersJob(BaseModel): status: Optional[Literal["pending", "in_progress", "completed", "failed", "expired"]] = None """Indicates the completion status of the background update.""" - successful_operations: Optional[List[SuccessfulOperation]] = None + successful_operations: Optional[List[PhoneNumbersJobSuccessfulOperation]] = None type: Optional[Literal["update_emergency_settings", "delete_phone_numbers", "update_phone_numbers"]] = None """Identifies the type of the background job.""" diff --git a/src/telnyx/types/phone_numbers/phone_numbers_job_pending_operation.py b/src/telnyx/types/phone_numbers/phone_numbers_job_pending_operation.py new file mode 100644 index 000000000..21cec5b85 --- /dev/null +++ b/src/telnyx/types/phone_numbers/phone_numbers_job_pending_operation.py @@ -0,0 +1,17 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional + +from ..._models import BaseModel + +__all__ = ["PhoneNumbersJobPendingOperation"] + + +class PhoneNumbersJobPendingOperation(BaseModel): + id: Optional[str] = None + """The phone number's ID""" + + phone_number: Optional[str] = None + """The phone number in e164 format.""" diff --git a/src/telnyx/types/phone_numbers/phone_numbers_job_successful_operation.py b/src/telnyx/types/phone_numbers/phone_numbers_job_successful_operation.py new file mode 100644 index 000000000..f1516438c --- /dev/null +++ b/src/telnyx/types/phone_numbers/phone_numbers_job_successful_operation.py @@ -0,0 +1,17 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional + +from ..._models import BaseModel + +__all__ = ["PhoneNumbersJobSuccessfulOperation"] + + +class PhoneNumbersJobSuccessfulOperation(BaseModel): + id: Optional[str] = None + """The phone number's ID""" + + phone_number: Optional[str] = None + """The phone number in e164 format.""" diff --git a/src/telnyx/types/session.py b/src/telnyx/types/session.py index 61095882f..9e36700d5 100644 --- a/src/telnyx/types/session.py +++ b/src/telnyx/types/session.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import List, Optional +from typing import Dict, List, Optional from datetime import datetime from typing_extensions import Literal @@ -36,7 +36,7 @@ class Session(BaseModel): limits: Limits - metadata: object + metadata: Dict[str, object] policy: Policy diff --git a/src/telnyx/types/telephony_credential.py b/src/telnyx/types/telephony_credential.py index 87f00613f..f0384fdda 100644 --- a/src/telnyx/types/telephony_credential.py +++ b/src/telnyx/types/telephony_credential.py @@ -5,6 +5,7 @@ from typing import Optional from .._models import BaseModel +from .token_material import TokenMaterial __all__ = ["TelephonyCredential"] @@ -36,6 +37,12 @@ class TelephonyCredential(BaseModel): sip_username: Optional[str] = None """The randomly generated SIP username for the credential.""" + token_material: Optional[TokenMaterial] = None + """Returned when the credential is created. + + See `GET /telephony_credentials/{id}/token_material` to fetch it again. + """ + updated_at: Optional[str] = None """ISO-8601 formatted date indicating when the resource was updated.""" diff --git a/src/telnyx/types/telephony_credential_retrieve_token_material_response.py b/src/telnyx/types/telephony_credential_retrieve_token_material_response.py new file mode 100644 index 000000000..1e789f269 --- /dev/null +++ b/src/telnyx/types/telephony_credential_retrieve_token_material_response.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional + +from .._models import BaseModel +from .token_material import TokenMaterial + +__all__ = ["TelephonyCredentialRetrieveTokenMaterialResponse"] + + +class TelephonyCredentialRetrieveTokenMaterialResponse(BaseModel): + data: Optional[TokenMaterial] = None + """ + What a server needs to mint login tokens for the credential itself, with no + request per token (`TelephonyCredential#to_jwt` in telnyx-ruby 3.1.0 or later). + As sensitive as `sip_password`: keep it on the server. + """ diff --git a/src/telnyx/types/token_material.py b/src/telnyx/types/token_material.py new file mode 100644 index 000000000..5a33f9759 --- /dev/null +++ b/src/telnyx/types/token_material.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional + +from .._models import BaseModel + +__all__ = ["TokenMaterial"] + + +class TokenMaterial(BaseModel): + """ + What a server needs to mint login tokens for the credential itself, with no request per token (`TelephonyCredential#to_jwt` in telnyx-ruby 3.1.0 or later). As sensitive as `sip_password`: keep it on the server. + """ + + kid: Optional[str] = None + """Identifies the Telnyx signing key the `signing_secret` was derived with. + + Goes in the token header. + """ + + signing_secret: Optional[str] = None + """The HMAC-SHA256 key the token is signed with, base64url without padding.""" + + tel_token: Optional[str] = None + """Opaque value Telnyx uses to resolve the credential. + + Carried in the token's `tel_token` claim as is. + """ diff --git a/src/telnyx/types/tts_integrations/__init__.py b/src/telnyx/types/tts_integrations/__init__.py deleted file mode 100644 index f8ee8b14b..000000000 --- a/src/telnyx/types/tts_integrations/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations diff --git a/src/telnyx/types/variable_schema_entry.py b/src/telnyx/types/variable_schema_entry.py new file mode 100644 index 000000000..2436a3680 --- /dev/null +++ b/src/telnyx/types/variable_schema_entry.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional + +from .._models import BaseModel + +__all__ = ["VariableSchemaEntry"] + + +class VariableSchemaEntry(BaseModel): + required: bool + """ + Whether the variable must be supplied when strict variable validation is + enabled. + """ + + default: Optional[str] = None + """Default value for an optional variable. Rejected when `required` is `true`.""" diff --git a/src/telnyx/types/variable_schema_entry_param.py b/src/telnyx/types/variable_schema_entry_param.py new file mode 100644 index 000000000..b4d8bd0e1 --- /dev/null +++ b/src/telnyx/types/variable_schema_entry_param.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["VariableSchemaEntryParam"] + + +class VariableSchemaEntryParam(TypedDict, total=False): + required: Required[bool] + """ + Whether the variable must be supplied when strict variable validation is + enabled. + """ + + default: str + """Default value for an optional variable. Rejected when `required` is `true`.""" diff --git a/src/telnyx/types/voice_clone_create_from_upload_params.py b/src/telnyx/types/voice_clone_create_from_upload_params.py index afae913da..e5bf62f89 100644 --- a/src/telnyx/types/voice_clone_create_from_upload_params.py +++ b/src/telnyx/types/voice_clone_create_from_upload_params.py @@ -131,7 +131,7 @@ class VoiceCloneUploadRequestTelnyxBayanClone(TypedDict, total=False): Defaults to `ar`. Other values return `422`. """ - provider: Literal["telnyx", "Telnyx"] + provider: Literal["telnyx"] """Voice synthesis provider. Defaults to `telnyx`.""" @@ -193,7 +193,7 @@ class VoiceCloneUploadRequestResembleClone(TypedDict, total=False): name: Required[str] """Name for the voice clone.""" - provider: Required[Literal["resemble", "Resemble"]] + provider: Required[Literal["resemble"]] """Voice synthesis provider. Must be `resemble`.""" label: str diff --git a/src/telnyx/types/voice_clone_data.py b/src/telnyx/types/voice_clone_data.py index 28eb76141..8acb460ba 100644 --- a/src/telnyx/types/voice_clone_data.py +++ b/src/telnyx/types/voice_clone_data.py @@ -45,7 +45,7 @@ class VoiceCloneData(BaseModel): name: Optional[str] = None """Name of the voice clone.""" - provider: Optional[Literal["telnyx", "minimax"]] = None + provider: Optional[Literal["telnyx", "minimax", "resemble"]] = None """Voice synthesis provider used for this clone.""" provider_supported_models: Optional[List[str]] = None diff --git a/src/telnyx/types/voice_clone_list_params.py b/src/telnyx/types/voice_clone_list_params.py index 1c66e06b6..674edd4e6 100644 --- a/src/telnyx/types/voice_clone_list_params.py +++ b/src/telnyx/types/voice_clone_list_params.py @@ -19,7 +19,7 @@ class VoiceCloneListParams(TypedDict, total=False): filter_name: Annotated[str, PropertyInfo(alias="filter[name]")] """Case-insensitive substring filter on the name field.""" - filter_provider: Annotated[Literal["telnyx", "minimax"], PropertyInfo(alias="filter[provider]")] + filter_provider: Annotated[Literal["telnyx", "minimax", "resemble"], PropertyInfo(alias="filter[provider]")] """Filter by voice synthesis provider. Case-insensitive.""" page_number: Annotated[int, PropertyInfo(alias="page[number]")] diff --git a/src/telnyx/types/whatsapp/__init__.py b/src/telnyx/types/whatsapp/__init__.py index 5abb19e36..a896e41db 100644 --- a/src/telnyx/types/whatsapp/__init__.py +++ b/src/telnyx/types/whatsapp/__init__.py @@ -39,11 +39,11 @@ if TYPE_CHECKING: from .whatsapp_user_data import WhatsappUserData as WhatsappUserData from .signup_list_response import SignupListResponse as SignupListResponse + from .whatsapp_hosted_signup import WhatsappHostedSignup as WhatsappHostedSignup + from .whatsapp_phone_response import WhatsappPhoneResponse as WhatsappPhoneResponse from .template_create_response import TemplateCreateResponse as TemplateCreateResponse from .phone_number_get_response import PhoneNumberGetResponse as PhoneNumberGetResponse from .user_data_update_response import UserDataUpdateResponse as UserDataUpdateResponse - from .phone_number_list_response import PhoneNumberListResponse as PhoneNumberListResponse - from .hosted_signup_list_response import HostedSignupListResponse as HostedSignupListResponse from .user_data_retrieve_response import UserDataRetrieveResponse as UserDataRetrieveResponse from .hosted_signup_create_response import HostedSignupCreateResponse as HostedSignupCreateResponse from .business_account_list_response import BusinessAccountListResponse as BusinessAccountListResponse @@ -71,10 +71,10 @@ def __getattr__(name: str) -> Any: from .template_create_response import TemplateCreateResponse return TemplateCreateResponse - if name == "PhoneNumberListResponse": - from .phone_number_list_response import PhoneNumberListResponse + if name == "WhatsappPhoneResponse": + from .whatsapp_phone_response import WhatsappPhoneResponse - return PhoneNumberListResponse + return WhatsappPhoneResponse if name == "PhoneNumberGetResponse": from .phone_number_get_response import PhoneNumberGetResponse @@ -107,6 +107,10 @@ def __getattr__(name: str) -> Any: from .signup_retrieve_status_response import SignupRetrieveStatusResponse return SignupRetrieveStatusResponse + if name == "WhatsappHostedSignup": + from .whatsapp_hosted_signup import WhatsappHostedSignup + + return WhatsappHostedSignup if name == "HostedSignupCreateResponse": from .hosted_signup_create_response import HostedSignupCreateResponse @@ -115,8 +119,4 @@ def __getattr__(name: str) -> Any: from .hosted_signup_retrieve_response import HostedSignupRetrieveResponse return HostedSignupRetrieveResponse - if name == "HostedSignupListResponse": - from .hosted_signup_list_response import HostedSignupListResponse - - return HostedSignupListResponse raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/src/telnyx/types/whatsapp/business_accounts/__init__.py b/src/telnyx/types/whatsapp/business_accounts/__init__.py index 268d7f08c..62c0cad6a 100644 --- a/src/telnyx/types/whatsapp/business_accounts/__init__.py +++ b/src/telnyx/types/whatsapp/business_accounts/__init__.py @@ -14,14 +14,9 @@ from .waba_settings import WabaSettings as WabaSettings from .setting_update_response import SettingUpdateResponse as SettingUpdateResponse from .setting_retrieve_response import SettingRetrieveResponse as SettingRetrieveResponse - from .phone_number_list_response import PhoneNumberListResponse as PhoneNumberListResponse def __getattr__(name: str) -> Any: - if name == "PhoneNumberListResponse": - from .phone_number_list_response import PhoneNumberListResponse - - return PhoneNumberListResponse if name == "WabaSettings": from .waba_settings import WabaSettings diff --git a/src/telnyx/types/whatsapp/business_accounts/phone_number_list_response.py b/src/telnyx/types/whatsapp/business_accounts/phone_number_list_response.py deleted file mode 100644 index 50b736454..000000000 --- a/src/telnyx/types/whatsapp/business_accounts/phone_number_list_response.py +++ /dev/null @@ -1,93 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Optional -from datetime import datetime -from typing_extensions import Literal - -from ...._models import BaseModel - -__all__ = ["PhoneNumberListResponse", "SyncProgress"] - - -class SyncProgress(BaseModel): - """Synchronization progress. - - This object is returned only while a coexistence number is synchronizing. - """ - - contacts_status: Optional[str] = None - - history_chunk_order: Optional[int] = None - - history_phase: Optional[int] = None - - history_progress: Optional[int] = None - - history_status: Optional[str] = None - - -class PhoneNumberListResponse(BaseModel): - calling_enabled: Optional[bool] = None - - coexistence_state: Optional[ - Literal[ - "pending_onboarding", - "sync_pending", - "syncing", - "sync_complete", - "active", - "history_declined", - "sync_deadline_expired", - "offboarded", - "disconnected", - ] - ] = None - """Current lifecycle state for a coexistence number. - - This is null for a standard Cloud API number. - """ - - created_at: Optional[datetime] = None - - display_name: Optional[str] = None - - enabled: Optional[bool] = None - - is_on_biz_app: Optional[bool] = None - """ - Indicates whether the number is connected to both the WhatsApp Business app and - Cloud API through WhatsApp Coexistence. - """ - - phone_number: Optional[str] = None - """Phone number in E164 format""" - - phone_number_id: Optional[str] = None - """Whatsapp phone number ID""" - - quality_rating: Optional[str] = None - """Whatsapp quality rating""" - - record_type: Optional[str] = None - - status: Optional[str] = None - - sync_deadline: Optional[datetime] = None - """Deadline for initiating the current coexistence synchronization cycle. - - This is null when no deadline applies. - """ - - sync_progress: Optional[SyncProgress] = None - """Synchronization progress. - - This object is returned only while a coexistence number is synchronizing. - """ - - user_id: Optional[str] = None - """User ID""" - - waba_id: Optional[str] = None - """WABA ID of Whatsapp business account""" diff --git a/src/telnyx/types/whatsapp/hosted_signup_create_response.py b/src/telnyx/types/whatsapp/hosted_signup_create_response.py index 45e09d6cb..a77fa76ae 100644 --- a/src/telnyx/types/whatsapp/hosted_signup_create_response.py +++ b/src/telnyx/types/whatsapp/hosted_signup_create_response.py @@ -3,40 +3,12 @@ from __future__ import annotations from typing import Optional -from datetime import datetime -from typing_extensions import Literal from ..._models import BaseModel +from .whatsapp_hosted_signup import WhatsappHostedSignup -__all__ = ["HostedSignupCreateResponse", "Data"] - - -class Data(BaseModel): - id: Optional[str] = None - """Hosted signup ID""" - - app_id: Optional[str] = None - """Meta App ID the hosted signup onboards customers into""" - - created_at: Optional[datetime] = None - - expires_at: Optional[datetime] = None - """When the onboarding URL stops working""" - - jwt: Optional[str] = None - """Signed token embedded in `url`""" - - record_type: Optional[Literal["whatsapp_jwt"]] = None - - solution_id: Optional[str] = None - """Meta Partner Solution ID linked to the app. - - Returned only when creating a hosted signup. - """ - - url: Optional[str] = None - """Hosted onboarding URL to share with the end customer""" +__all__ = ["HostedSignupCreateResponse"] class HostedSignupCreateResponse(BaseModel): - data: Optional[Data] = None + data: Optional[WhatsappHostedSignup] = None diff --git a/src/telnyx/types/whatsapp/hosted_signup_retrieve_response.py b/src/telnyx/types/whatsapp/hosted_signup_retrieve_response.py index a166a8bb7..4769be996 100644 --- a/src/telnyx/types/whatsapp/hosted_signup_retrieve_response.py +++ b/src/telnyx/types/whatsapp/hosted_signup_retrieve_response.py @@ -3,40 +3,12 @@ from __future__ import annotations from typing import Optional -from datetime import datetime -from typing_extensions import Literal from ..._models import BaseModel +from .whatsapp_hosted_signup import WhatsappHostedSignup -__all__ = ["HostedSignupRetrieveResponse", "Data"] - - -class Data(BaseModel): - id: Optional[str] = None - """Hosted signup ID""" - - app_id: Optional[str] = None - """Meta App ID the hosted signup onboards customers into""" - - created_at: Optional[datetime] = None - - expires_at: Optional[datetime] = None - """When the onboarding URL stops working""" - - jwt: Optional[str] = None - """Signed token embedded in `url`""" - - record_type: Optional[Literal["whatsapp_jwt"]] = None - - solution_id: Optional[str] = None - """Meta Partner Solution ID linked to the app. - - Returned only when creating a hosted signup. - """ - - url: Optional[str] = None - """Hosted onboarding URL to share with the end customer""" +__all__ = ["HostedSignupRetrieveResponse"] class HostedSignupRetrieveResponse(BaseModel): - data: Optional[Data] = None + data: Optional[WhatsappHostedSignup] = None diff --git a/src/telnyx/types/whatsapp/phone_number_get_response.py b/src/telnyx/types/whatsapp/phone_number_get_response.py index e1caf5441..4784d1456 100644 --- a/src/telnyx/types/whatsapp/phone_number_get_response.py +++ b/src/telnyx/types/whatsapp/phone_number_get_response.py @@ -3,98 +3,15 @@ from __future__ import annotations from typing import List, Optional -from datetime import datetime -from typing_extensions import Literal from ..._models import BaseModel +from .whatsapp_phone_response import WhatsappPhoneResponse from ..shared.messaging_pagination_meta import MessagingPaginationMeta -__all__ = ["PhoneNumberGetResponse", "Data", "DataSyncProgress"] - - -class DataSyncProgress(BaseModel): - """Synchronization progress. - - This object is returned only while a coexistence number is synchronizing. - """ - - contacts_status: Optional[str] = None - - history_chunk_order: Optional[int] = None - - history_phase: Optional[int] = None - - history_progress: Optional[int] = None - - history_status: Optional[str] = None - - -class Data(BaseModel): - calling_enabled: Optional[bool] = None - - coexistence_state: Optional[ - Literal[ - "pending_onboarding", - "sync_pending", - "syncing", - "sync_complete", - "active", - "history_declined", - "sync_deadline_expired", - "offboarded", - "disconnected", - ] - ] = None - """Current lifecycle state for a coexistence number. - - This is null for a standard Cloud API number. - """ - - created_at: Optional[datetime] = None - - display_name: Optional[str] = None - - enabled: Optional[bool] = None - - is_on_biz_app: Optional[bool] = None - """ - Indicates whether the number is connected to both the WhatsApp Business app and - Cloud API through WhatsApp Coexistence. - """ - - phone_number: Optional[str] = None - """Phone number in E164 format""" - - phone_number_id: Optional[str] = None - """Whatsapp phone number ID""" - - quality_rating: Optional[str] = None - """Whatsapp quality rating""" - - record_type: Optional[str] = None - - status: Optional[str] = None - - sync_deadline: Optional[datetime] = None - """Deadline for initiating the current coexistence synchronization cycle. - - This is null when no deadline applies. - """ - - sync_progress: Optional[DataSyncProgress] = None - """Synchronization progress. - - This object is returned only while a coexistence number is synchronizing. - """ - - user_id: Optional[str] = None - """User ID""" - - waba_id: Optional[str] = None - """WABA ID of Whatsapp business account""" +__all__ = ["PhoneNumberGetResponse"] class PhoneNumberGetResponse(BaseModel): - data: Optional[List[Data]] = None + data: Optional[List[WhatsappPhoneResponse]] = None meta: Optional[MessagingPaginationMeta] = None diff --git a/src/telnyx/types/whatsapp/phone_number_retrieve_phone_number_response.py b/src/telnyx/types/whatsapp/phone_number_retrieve_phone_number_response.py index 1bc577231..05fe1a3d0 100644 --- a/src/telnyx/types/whatsapp/phone_number_retrieve_phone_number_response.py +++ b/src/telnyx/types/whatsapp/phone_number_retrieve_phone_number_response.py @@ -2,96 +2,11 @@ from __future__ import annotations -from typing import Optional -from datetime import datetime -from typing_extensions import Literal - from ..._models import BaseModel +from .whatsapp_phone_response import WhatsappPhoneResponse -__all__ = ["PhoneNumberRetrievePhoneNumberResponse", "Data", "DataSyncProgress"] - - -class DataSyncProgress(BaseModel): - """Synchronization progress. - - This object is returned only while a coexistence number is synchronizing. - """ - - contacts_status: Optional[str] = None - - history_chunk_order: Optional[int] = None - - history_phase: Optional[int] = None - - history_progress: Optional[int] = None - - history_status: Optional[str] = None - - -class Data(BaseModel): - calling_enabled: Optional[bool] = None - - coexistence_state: Optional[ - Literal[ - "pending_onboarding", - "sync_pending", - "syncing", - "sync_complete", - "active", - "history_declined", - "sync_deadline_expired", - "offboarded", - "disconnected", - ] - ] = None - """Current lifecycle state for a coexistence number. - - This is null for a standard Cloud API number. - """ - - created_at: Optional[datetime] = None - - display_name: Optional[str] = None - - enabled: Optional[bool] = None - - is_on_biz_app: Optional[bool] = None - """ - Indicates whether the number is connected to both the WhatsApp Business app and - Cloud API through WhatsApp Coexistence. - """ - - phone_number: Optional[str] = None - """Phone number in E164 format""" - - phone_number_id: Optional[str] = None - """Whatsapp phone number ID""" - - quality_rating: Optional[str] = None - """Whatsapp quality rating""" - - record_type: Optional[str] = None - - status: Optional[str] = None - - sync_deadline: Optional[datetime] = None - """Deadline for initiating the current coexistence synchronization cycle. - - This is null when no deadline applies. - """ - - sync_progress: Optional[DataSyncProgress] = None - """Synchronization progress. - - This object is returned only while a coexistence number is synchronizing. - """ - - user_id: Optional[str] = None - """User ID""" - - waba_id: Optional[str] = None - """WABA ID of Whatsapp business account""" +__all__ = ["PhoneNumberRetrievePhoneNumberResponse"] class PhoneNumberRetrievePhoneNumberResponse(BaseModel): - data: Data + data: WhatsappPhoneResponse diff --git a/src/telnyx/types/whatsapp/hosted_signup_list_response.py b/src/telnyx/types/whatsapp/whatsapp_hosted_signup.py similarity index 91% rename from src/telnyx/types/whatsapp/hosted_signup_list_response.py rename to src/telnyx/types/whatsapp/whatsapp_hosted_signup.py index 4c48a9639..5e7f8a9c3 100644 --- a/src/telnyx/types/whatsapp/hosted_signup_list_response.py +++ b/src/telnyx/types/whatsapp/whatsapp_hosted_signup.py @@ -8,10 +8,10 @@ from ..._models import BaseModel -__all__ = ["HostedSignupListResponse"] +__all__ = ["WhatsappHostedSignup"] -class HostedSignupListResponse(BaseModel): +class WhatsappHostedSignup(BaseModel): id: Optional[str] = None """Hosted signup ID""" diff --git a/src/telnyx/types/whatsapp/phone_number_list_response.py b/src/telnyx/types/whatsapp/whatsapp_phone_response.py similarity index 95% rename from src/telnyx/types/whatsapp/phone_number_list_response.py rename to src/telnyx/types/whatsapp/whatsapp_phone_response.py index 0d8e59fcf..32e36e9f1 100644 --- a/src/telnyx/types/whatsapp/phone_number_list_response.py +++ b/src/telnyx/types/whatsapp/whatsapp_phone_response.py @@ -8,7 +8,7 @@ from ..._models import BaseModel -__all__ = ["PhoneNumberListResponse", "SyncProgress"] +__all__ = ["WhatsappPhoneResponse", "SyncProgress"] class SyncProgress(BaseModel): @@ -28,7 +28,7 @@ class SyncProgress(BaseModel): history_status: Optional[str] = None -class PhoneNumberListResponse(BaseModel): +class WhatsappPhoneResponse(BaseModel): calling_enabled: Optional[bool] = None coexistence_state: Optional[ diff --git a/tests/api_resources/ai/assistants/test_versions.py b/tests/api_resources/ai/assistants/test_versions.py index bf82c83fd..524ae5108 100644 --- a/tests/api_resources/ai/assistants/test_versions.py +++ b/tests/api_resources/ai/assistants/test_versions.py @@ -544,6 +544,7 @@ def test_method_update_with_all_params(self, client: Telnyx) -> None: "default_texml_app_id": "default_texml_app_id", "disable_dtmf": True, "fallback_destination": "fallback_destination", + "greeting_delay_ms": 0, "noise_suppression": "aicoustics", "noise_suppression_config": { "attenuation_limit": 0, @@ -1444,6 +1445,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncTelnyx) -> "default_texml_app_id": "default_texml_app_id", "disable_dtmf": True, "fallback_destination": "fallback_destination", + "greeting_delay_ms": 0, "noise_suppression": "aicoustics", "noise_suppression_config": { "attenuation_limit": 0, diff --git a/tests/api_resources/ai/test_assistants.py b/tests/api_resources/ai/test_assistants.py index 31a7d793a..1ba41ca31 100644 --- a/tests/api_resources/ai/test_assistants.py +++ b/tests/api_resources/ai/test_assistants.py @@ -484,6 +484,7 @@ def test_method_create_with_all_params(self, client: Telnyx) -> None: "default_texml_app_id": "default_texml_app_id", "disable_dtmf": True, "fallback_destination": "fallback_destination", + "greeting_delay_ms": 0, "noise_suppression": "aicoustics", "noise_suppression_config": { "attenuation_limit": 0, @@ -1208,6 +1209,7 @@ def test_method_update_with_all_params(self, client: Telnyx) -> None: "default_texml_app_id": "default_texml_app_id", "disable_dtmf": True, "fallback_destination": "fallback_destination", + "greeting_delay_ms": 0, "noise_suppression": "aicoustics", "noise_suppression_config": { "attenuation_limit": 0, @@ -2344,6 +2346,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncTelnyx) -> "default_texml_app_id": "default_texml_app_id", "disable_dtmf": True, "fallback_destination": "fallback_destination", + "greeting_delay_ms": 0, "noise_suppression": "aicoustics", "noise_suppression_config": { "attenuation_limit": 0, @@ -3068,6 +3071,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncTelnyx) -> "default_texml_app_id": "default_texml_app_id", "disable_dtmf": True, "fallback_destination": "fallback_destination", + "greeting_delay_ms": 0, "noise_suppression": "aicoustics", "noise_suppression_config": { "attenuation_limit": 0, diff --git a/tests/api_resources/ai/test_tools.py b/tests/api_resources/ai/test_tools.py index 9521db7a9..270846153 100644 --- a/tests/api_resources/ai/test_tools.py +++ b/tests/api_resources/ai/test_tools.py @@ -47,7 +47,20 @@ def test_method_create_with_all_params(self, client: Telnyx) -> None: }, "currency": "currency", "description": "description", + "inter_digit_timeout_millis": 1, + "max_attempts": 1, + "min_postal_code_length": 5, "payment_method": "payment_method", + "postal_code": False, + "prompts": { + "bank_account_number": "x", + "bank_routing_number": "x", + "expiration_date": "x", + "payment_card_number": "x", + "postal_code": "x", + "security_code": "x", + }, + "timeout_millis": 12000, "valid_card_types": ["visa", "mastercard"], }, retrieval={"foo": "bar"}, @@ -165,7 +178,20 @@ def test_method_update_with_all_params(self, client: Telnyx) -> None: }, "currency": "currency", "description": "description", + "inter_digit_timeout_millis": 1, + "max_attempts": 1, + "min_postal_code_length": 5, "payment_method": "payment_method", + "postal_code": False, + "prompts": { + "bank_account_number": "x", + "bank_routing_number": "x", + "expiration_date": "x", + "payment_card_number": "x", + "postal_code": "x", + "security_code": "x", + }, + "timeout_millis": 12000, "valid_card_types": ["visa", "mastercard"], }, retrieval={"foo": "bar"}, @@ -335,7 +361,20 @@ async def test_method_create_with_all_params(self, async_client: AsyncTelnyx) -> }, "currency": "currency", "description": "description", + "inter_digit_timeout_millis": 1, + "max_attempts": 1, + "min_postal_code_length": 5, "payment_method": "payment_method", + "postal_code": False, + "prompts": { + "bank_account_number": "x", + "bank_routing_number": "x", + "expiration_date": "x", + "payment_card_number": "x", + "postal_code": "x", + "security_code": "x", + }, + "timeout_millis": 12000, "valid_card_types": ["visa", "mastercard"], }, retrieval={"foo": "bar"}, @@ -453,7 +492,20 @@ async def test_method_update_with_all_params(self, async_client: AsyncTelnyx) -> }, "currency": "currency", "description": "description", + "inter_digit_timeout_millis": 1, + "max_attempts": 1, + "min_postal_code_length": 5, "payment_method": "payment_method", + "postal_code": False, + "prompts": { + "bank_account_number": "x", + "bank_routing_number": "x", + "expiration_date": "x", + "payment_card_number": "x", + "postal_code": "x", + "security_code": "x", + }, + "timeout_millis": 12000, "valid_card_types": ["visa", "mastercard"], }, retrieval={"foo": "bar"}, diff --git a/tests/api_resources/test_browser_sessions.py b/tests/api_resources/test_browser_sessions.py index 5feabe0a0..bc081626d 100644 --- a/tests/api_resources/test_browser_sessions.py +++ b/tests/api_resources/test_browser_sessions.py @@ -41,7 +41,7 @@ def test_method_create_with_all_params(self, client: Telnyx) -> None: "idle_timeout_s": 30, "lifetime_s": 60, }, - metadata={}, + metadata={"foo": "bar"}, ) assert_matches_type(BrowserSessionCreateResponse, browser_session, path=["response"]) @@ -267,7 +267,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncTelnyx) -> "idle_timeout_s": 30, "lifetime_s": 60, }, - metadata={}, + metadata={"foo": "bar"}, ) assert_matches_type(BrowserSessionCreateResponse, browser_session, path=["response"]) diff --git a/tests/api_resources/test_email_events.py b/tests/api_resources/test_email_events.py index b1e51fdcd..28fb10bde 100644 --- a/tests/api_resources/test_email_events.py +++ b/tests/api_resources/test_email_events.py @@ -14,6 +14,7 @@ EmailEventRetrieveStatsResponse, ) from telnyx._utils import parse_datetime +from telnyx.pagination import SyncEmailEventsCursorPagination, AsyncEmailEventsCursorPagination base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -25,7 +26,7 @@ class TestEmailEvents: @parametrize def test_method_list(self, client: Telnyx) -> None: email_event = client.email_events.list() - assert_matches_type(EmailEventListResponse, email_event, path=["response"]) + assert_matches_type(SyncEmailEventsCursorPagination[EmailEventListResponse], email_event, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -38,7 +39,7 @@ def test_method_list_with_all_params(self, client: Telnyx) -> None: page_cursor="page[cursor]", to=parse_datetime("2019-12-27T18:11:19.117Z"), ) - assert_matches_type(EmailEventListResponse, email_event, path=["response"]) + assert_matches_type(SyncEmailEventsCursorPagination[EmailEventListResponse], email_event, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -48,7 +49,7 @@ def test_raw_response_list(self, client: Telnyx) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" email_event = response.parse() - assert_matches_type(EmailEventListResponse, email_event, path=["response"]) + assert_matches_type(SyncEmailEventsCursorPagination[EmailEventListResponse], email_event, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -58,7 +59,7 @@ def test_streaming_response_list(self, client: Telnyx) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" email_event = response.parse() - assert_matches_type(EmailEventListResponse, email_event, path=["response"]) + assert_matches_type(SyncEmailEventsCursorPagination[EmailEventListResponse], email_event, path=["response"]) assert cast(Any, response.is_closed) is True @@ -109,7 +110,7 @@ class TestAsyncEmailEvents: @parametrize async def test_method_list(self, async_client: AsyncTelnyx) -> None: email_event = await async_client.email_events.list() - assert_matches_type(EmailEventListResponse, email_event, path=["response"]) + assert_matches_type(AsyncEmailEventsCursorPagination[EmailEventListResponse], email_event, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -122,7 +123,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncTelnyx) -> N page_cursor="page[cursor]", to=parse_datetime("2019-12-27T18:11:19.117Z"), ) - assert_matches_type(EmailEventListResponse, email_event, path=["response"]) + assert_matches_type(AsyncEmailEventsCursorPagination[EmailEventListResponse], email_event, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -132,7 +133,7 @@ async def test_raw_response_list(self, async_client: AsyncTelnyx) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" email_event = await response.parse() - assert_matches_type(EmailEventListResponse, email_event, path=["response"]) + assert_matches_type(AsyncEmailEventsCursorPagination[EmailEventListResponse], email_event, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -142,7 +143,9 @@ async def test_streaming_response_list(self, async_client: AsyncTelnyx) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" email_event = await response.parse() - assert_matches_type(EmailEventListResponse, email_event, path=["response"]) + assert_matches_type( + AsyncEmailEventsCursorPagination[EmailEventListResponse], email_event, path=["response"] + ) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_messages.py b/tests/api_resources/test_messages.py index 223c928fc..0bad8bb88 100644 --- a/tests/api_resources/test_messages.py +++ b/tests/api_resources/test_messages.py @@ -672,7 +672,7 @@ def test_method_whatsapp_with_all_params(self, client: Telnyx) -> None: "display_text": "display_text", "flow_action": "navigate", "flow_action_payload": { - "data": {}, + "data": {"foo": "bar"}, "screen": "screen", }, "flow_cta": "flow_cta", @@ -748,7 +748,7 @@ def test_method_whatsapp_with_all_params(self, client: Telnyx) -> None: "parameters": [ { "action": { - "flow_action_data": {}, + "flow_action_data": {"foo": "bar"}, "flow_token": "flow_token", }, "text": "text", @@ -1463,7 +1463,7 @@ async def test_method_whatsapp_with_all_params(self, async_client: AsyncTelnyx) "display_text": "display_text", "flow_action": "navigate", "flow_action_payload": { - "data": {}, + "data": {"foo": "bar"}, "screen": "screen", }, "flow_cta": "flow_cta", @@ -1539,7 +1539,7 @@ async def test_method_whatsapp_with_all_params(self, async_client: AsyncTelnyx) "parameters": [ { "action": { - "flow_action_data": {}, + "flow_action_data": {"foo": "bar"}, "flow_token": "flow_token", }, "text": "text", diff --git a/tests/api_resources/test_messaging_profiles.py b/tests/api_resources/test_messaging_profiles.py index 27ed766e0..bb67b62b0 100644 --- a/tests/api_resources/test_messaging_profiles.py +++ b/tests/api_resources/test_messaging_profiles.py @@ -47,7 +47,10 @@ def test_method_create_with_all_params(self, client: Telnyx) -> None: daily_spend_limit="269125115713", daily_spend_limit_enabled=True, enabled=True, - features={"ai_opt_out_detection_enabled": True}, + features={ + "ai_opt_out_detection_enabled": True, + "auto_chunk_long_messages": True, + }, health_webhook_url="health_webhook_url", mm7_metadata={ "mm7_failover_webhook_url": "https://backup.example.com/hooks", @@ -165,7 +168,10 @@ def test_method_update_with_all_params(self, client: Telnyx) -> None: daily_spend_limit="269125115713", daily_spend_limit_enabled=True, enabled=True, - features={"ai_opt_out_detection_enabled": True}, + features={ + "ai_opt_out_detection_enabled": True, + "auto_chunk_long_messages": True, + }, mm7_metadata={ "mm7_failover_webhook_url": "https://backup.example.com/hooks", "mm7_webhook_url": "https://www.example.com/hooks", @@ -557,7 +563,10 @@ async def test_method_create_with_all_params(self, async_client: AsyncTelnyx) -> daily_spend_limit="269125115713", daily_spend_limit_enabled=True, enabled=True, - features={"ai_opt_out_detection_enabled": True}, + features={ + "ai_opt_out_detection_enabled": True, + "auto_chunk_long_messages": True, + }, health_webhook_url="health_webhook_url", mm7_metadata={ "mm7_failover_webhook_url": "https://backup.example.com/hooks", @@ -675,7 +684,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncTelnyx) -> daily_spend_limit="269125115713", daily_spend_limit_enabled=True, enabled=True, - features={"ai_opt_out_detection_enabled": True}, + features={ + "ai_opt_out_detection_enabled": True, + "auto_chunk_long_messages": True, + }, mm7_metadata={ "mm7_failover_webhook_url": "https://backup.example.com/hooks", "mm7_webhook_url": "https://www.example.com/hooks", diff --git a/tests/api_resources/test_pay_connectors.py b/tests/api_resources/test_pay_connectors.py index 74329ea2f..6d506d334 100644 --- a/tests/api_resources/test_pay_connectors.py +++ b/tests/api_resources/test_pay_connectors.py @@ -36,11 +36,11 @@ def test_method_create_with_all_params(self, client: Telnyx) -> None: pay_connector = client.pay_connectors.create( config={ "auth_type": "none", - "token": {}, + "token": "token", "endpoint_url": "https://processor.example.com/pay", - "password": {}, + "password": "password", "timeout": 1, - "username": {}, + "username": "username", }, name="my-payment-connector", mode="test", @@ -134,7 +134,7 @@ def test_method_update_with_all_params(self, client: Telnyx) -> None: config={ "password": "P", "username": "P", - "token": {}, + "token": "token", "auth_type": "basic", "endpoint_url": "https://processor.example.com/pay", "timeout": 1, @@ -293,11 +293,11 @@ async def test_method_create_with_all_params(self, async_client: AsyncTelnyx) -> pay_connector = await async_client.pay_connectors.create( config={ "auth_type": "none", - "token": {}, + "token": "token", "endpoint_url": "https://processor.example.com/pay", - "password": {}, + "password": "password", "timeout": 1, - "username": {}, + "username": "username", }, name="my-payment-connector", mode="test", @@ -391,7 +391,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncTelnyx) -> config={ "password": "P", "username": "P", - "token": {}, + "token": "token", "auth_type": "basic", "endpoint_url": "https://processor.example.com/pay", "timeout": 1, diff --git a/tests/api_resources/test_telephony_credentials.py b/tests/api_resources/test_telephony_credentials.py index 23663d892..953e8d36f 100644 --- a/tests/api_resources/test_telephony_credentials.py +++ b/tests/api_resources/test_telephony_credentials.py @@ -15,6 +15,7 @@ TelephonyCredentialDeleteResponse, TelephonyCredentialUpdateResponse, TelephonyCredentialRetrieveResponse, + TelephonyCredentialRetrieveTokenMaterialResponse, ) from telnyx.pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination @@ -302,6 +303,50 @@ def test_path_params_create_token(self, client: Telnyx) -> None: id="", ) + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_retrieve_token_material(self, client: Telnyx) -> None: + telephony_credential = client.telephony_credentials.retrieve_token_material( + "id", + ) + assert_matches_type(TelephonyCredentialRetrieveTokenMaterialResponse, telephony_credential, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_retrieve_token_material(self, client: Telnyx) -> None: + response = client.telephony_credentials.with_raw_response.retrieve_token_material( + "id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + telephony_credential = response.parse() + assert_matches_type(TelephonyCredentialRetrieveTokenMaterialResponse, telephony_credential, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_retrieve_token_material(self, client: Telnyx) -> None: + with client.telephony_credentials.with_streaming_response.retrieve_token_material( + "id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + telephony_credential = response.parse() + assert_matches_type( + TelephonyCredentialRetrieveTokenMaterialResponse, telephony_credential, path=["response"] + ) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_retrieve_token_material(self, client: Telnyx) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.telephony_credentials.with_raw_response.retrieve_token_material( + "", + ) + class TestAsyncTelephonyCredentials: parametrize = pytest.mark.parametrize( @@ -587,3 +632,47 @@ async def test_path_params_create_token(self, async_client: AsyncTelnyx) -> None await async_client.telephony_credentials.with_raw_response.create_token( id="", ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_retrieve_token_material(self, async_client: AsyncTelnyx) -> None: + telephony_credential = await async_client.telephony_credentials.retrieve_token_material( + "id", + ) + assert_matches_type(TelephonyCredentialRetrieveTokenMaterialResponse, telephony_credential, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_retrieve_token_material(self, async_client: AsyncTelnyx) -> None: + response = await async_client.telephony_credentials.with_raw_response.retrieve_token_material( + "id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + telephony_credential = await response.parse() + assert_matches_type(TelephonyCredentialRetrieveTokenMaterialResponse, telephony_credential, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_retrieve_token_material(self, async_client: AsyncTelnyx) -> None: + async with async_client.telephony_credentials.with_streaming_response.retrieve_token_material( + "id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + telephony_credential = await response.parse() + assert_matches_type( + TelephonyCredentialRetrieveTokenMaterialResponse, telephony_credential, path=["response"] + ) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_retrieve_token_material(self, async_client: AsyncTelnyx) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.telephony_credentials.with_raw_response.retrieve_token_material( + "", + ) diff --git a/tests/api_resources/whatsapp/business_accounts/test_phone_numbers.py b/tests/api_resources/whatsapp/business_accounts/test_phone_numbers.py index 1b03ba2a8..6d3619df6 100644 --- a/tests/api_resources/whatsapp/business_accounts/test_phone_numbers.py +++ b/tests/api_resources/whatsapp/business_accounts/test_phone_numbers.py @@ -10,9 +10,7 @@ from telnyx import Telnyx, AsyncTelnyx from tests.utils import assert_matches_type from telnyx.pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination -from telnyx.types.whatsapp.business_accounts import ( - PhoneNumberListResponse, -) +from telnyx.types.whatsapp import WhatsappPhoneResponse base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -26,7 +24,7 @@ def test_method_list(self, client: Telnyx) -> None: phone_number = client.whatsapp.business_accounts.phone_numbers.list( id="id", ) - assert_matches_type(SyncDefaultFlatPagination[PhoneNumberListResponse], phone_number, path=["response"]) + assert_matches_type(SyncDefaultFlatPagination[WhatsappPhoneResponse], phone_number, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -36,7 +34,7 @@ def test_method_list_with_all_params(self, client: Telnyx) -> None: page_number=0, page_size=0, ) - assert_matches_type(SyncDefaultFlatPagination[PhoneNumberListResponse], phone_number, path=["response"]) + assert_matches_type(SyncDefaultFlatPagination[WhatsappPhoneResponse], phone_number, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -48,7 +46,7 @@ def test_raw_response_list(self, client: Telnyx) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" phone_number = response.parse() - assert_matches_type(SyncDefaultFlatPagination[PhoneNumberListResponse], phone_number, path=["response"]) + assert_matches_type(SyncDefaultFlatPagination[WhatsappPhoneResponse], phone_number, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -60,7 +58,7 @@ def test_streaming_response_list(self, client: Telnyx) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" phone_number = response.parse() - assert_matches_type(SyncDefaultFlatPagination[PhoneNumberListResponse], phone_number, path=["response"]) + assert_matches_type(SyncDefaultFlatPagination[WhatsappPhoneResponse], phone_number, path=["response"]) assert cast(Any, response.is_closed) is True @@ -146,7 +144,7 @@ async def test_method_list(self, async_client: AsyncTelnyx) -> None: phone_number = await async_client.whatsapp.business_accounts.phone_numbers.list( id="id", ) - assert_matches_type(AsyncDefaultFlatPagination[PhoneNumberListResponse], phone_number, path=["response"]) + assert_matches_type(AsyncDefaultFlatPagination[WhatsappPhoneResponse], phone_number, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -156,7 +154,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncTelnyx) -> N page_number=0, page_size=0, ) - assert_matches_type(AsyncDefaultFlatPagination[PhoneNumberListResponse], phone_number, path=["response"]) + assert_matches_type(AsyncDefaultFlatPagination[WhatsappPhoneResponse], phone_number, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -168,7 +166,7 @@ async def test_raw_response_list(self, async_client: AsyncTelnyx) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" phone_number = await response.parse() - assert_matches_type(AsyncDefaultFlatPagination[PhoneNumberListResponse], phone_number, path=["response"]) + assert_matches_type(AsyncDefaultFlatPagination[WhatsappPhoneResponse], phone_number, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -180,7 +178,7 @@ async def test_streaming_response_list(self, async_client: AsyncTelnyx) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" phone_number = await response.parse() - assert_matches_type(AsyncDefaultFlatPagination[PhoneNumberListResponse], phone_number, path=["response"]) + assert_matches_type(AsyncDefaultFlatPagination[WhatsappPhoneResponse], phone_number, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/whatsapp/test_hosted_signups.py b/tests/api_resources/whatsapp/test_hosted_signups.py index 7b50eba25..bf495512c 100644 --- a/tests/api_resources/whatsapp/test_hosted_signups.py +++ b/tests/api_resources/whatsapp/test_hosted_signups.py @@ -12,7 +12,7 @@ from telnyx._utils import parse_datetime from telnyx.pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination from telnyx.types.whatsapp import ( - HostedSignupListResponse, + WhatsappHostedSignup, HostedSignupCreateResponse, HostedSignupRetrieveResponse, ) @@ -113,7 +113,7 @@ def test_path_params_retrieve(self, client: Telnyx) -> None: @parametrize def test_method_list(self, client: Telnyx) -> None: hosted_signup = client.whatsapp.hosted_signups.list() - assert_matches_type(SyncDefaultFlatPagination[HostedSignupListResponse], hosted_signup, path=["response"]) + assert_matches_type(SyncDefaultFlatPagination[WhatsappHostedSignup], hosted_signup, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -122,7 +122,7 @@ def test_method_list_with_all_params(self, client: Telnyx) -> None: page_number=0, page_size=0, ) - assert_matches_type(SyncDefaultFlatPagination[HostedSignupListResponse], hosted_signup, path=["response"]) + assert_matches_type(SyncDefaultFlatPagination[WhatsappHostedSignup], hosted_signup, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -132,7 +132,7 @@ def test_raw_response_list(self, client: Telnyx) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" hosted_signup = response.parse() - assert_matches_type(SyncDefaultFlatPagination[HostedSignupListResponse], hosted_signup, path=["response"]) + assert_matches_type(SyncDefaultFlatPagination[WhatsappHostedSignup], hosted_signup, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -142,7 +142,7 @@ def test_streaming_response_list(self, client: Telnyx) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" hosted_signup = response.parse() - assert_matches_type(SyncDefaultFlatPagination[HostedSignupListResponse], hosted_signup, path=["response"]) + assert_matches_type(SyncDefaultFlatPagination[WhatsappHostedSignup], hosted_signup, path=["response"]) assert cast(Any, response.is_closed) is True @@ -242,7 +242,7 @@ async def test_path_params_retrieve(self, async_client: AsyncTelnyx) -> None: @parametrize async def test_method_list(self, async_client: AsyncTelnyx) -> None: hosted_signup = await async_client.whatsapp.hosted_signups.list() - assert_matches_type(AsyncDefaultFlatPagination[HostedSignupListResponse], hosted_signup, path=["response"]) + assert_matches_type(AsyncDefaultFlatPagination[WhatsappHostedSignup], hosted_signup, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -251,7 +251,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncTelnyx) -> N page_number=0, page_size=0, ) - assert_matches_type(AsyncDefaultFlatPagination[HostedSignupListResponse], hosted_signup, path=["response"]) + assert_matches_type(AsyncDefaultFlatPagination[WhatsappHostedSignup], hosted_signup, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -261,7 +261,7 @@ async def test_raw_response_list(self, async_client: AsyncTelnyx) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" hosted_signup = await response.parse() - assert_matches_type(AsyncDefaultFlatPagination[HostedSignupListResponse], hosted_signup, path=["response"]) + assert_matches_type(AsyncDefaultFlatPagination[WhatsappHostedSignup], hosted_signup, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -271,6 +271,6 @@ async def test_streaming_response_list(self, async_client: AsyncTelnyx) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" hosted_signup = await response.parse() - assert_matches_type(AsyncDefaultFlatPagination[HostedSignupListResponse], hosted_signup, path=["response"]) + assert_matches_type(AsyncDefaultFlatPagination[WhatsappHostedSignup], hosted_signup, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/whatsapp/test_phone_numbers.py b/tests/api_resources/whatsapp/test_phone_numbers.py index e96722396..f7fa975bd 100644 --- a/tests/api_resources/whatsapp/test_phone_numbers.py +++ b/tests/api_resources/whatsapp/test_phone_numbers.py @@ -11,8 +11,8 @@ from tests.utils import assert_matches_type from telnyx.pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination from telnyx.types.whatsapp import ( + WhatsappPhoneResponse, PhoneNumberGetResponse, - PhoneNumberListResponse, PhoneNumberRetrievePhoneNumberResponse, PhoneNumberRetrieveConversationWindowResponse, ) @@ -27,7 +27,7 @@ class TestPhoneNumbers: @parametrize def test_method_list(self, client: Telnyx) -> None: phone_number = client.whatsapp.phone_numbers.list() - assert_matches_type(SyncDefaultFlatPagination[PhoneNumberListResponse], phone_number, path=["response"]) + assert_matches_type(SyncDefaultFlatPagination[WhatsappPhoneResponse], phone_number, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -36,7 +36,7 @@ def test_method_list_with_all_params(self, client: Telnyx) -> None: page_number=0, page_size=0, ) - assert_matches_type(SyncDefaultFlatPagination[PhoneNumberListResponse], phone_number, path=["response"]) + assert_matches_type(SyncDefaultFlatPagination[WhatsappPhoneResponse], phone_number, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -46,7 +46,7 @@ def test_raw_response_list(self, client: Telnyx) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" phone_number = response.parse() - assert_matches_type(SyncDefaultFlatPagination[PhoneNumberListResponse], phone_number, path=["response"]) + assert_matches_type(SyncDefaultFlatPagination[WhatsappPhoneResponse], phone_number, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -56,7 +56,7 @@ def test_streaming_response_list(self, client: Telnyx) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" phone_number = response.parse() - assert_matches_type(SyncDefaultFlatPagination[PhoneNumberListResponse], phone_number, path=["response"]) + assert_matches_type(SyncDefaultFlatPagination[WhatsappPhoneResponse], phone_number, path=["response"]) assert cast(Any, response.is_closed) is True @@ -334,7 +334,7 @@ class TestAsyncPhoneNumbers: @parametrize async def test_method_list(self, async_client: AsyncTelnyx) -> None: phone_number = await async_client.whatsapp.phone_numbers.list() - assert_matches_type(AsyncDefaultFlatPagination[PhoneNumberListResponse], phone_number, path=["response"]) + assert_matches_type(AsyncDefaultFlatPagination[WhatsappPhoneResponse], phone_number, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -343,7 +343,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncTelnyx) -> N page_number=0, page_size=0, ) - assert_matches_type(AsyncDefaultFlatPagination[PhoneNumberListResponse], phone_number, path=["response"]) + assert_matches_type(AsyncDefaultFlatPagination[WhatsappPhoneResponse], phone_number, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -353,7 +353,7 @@ async def test_raw_response_list(self, async_client: AsyncTelnyx) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" phone_number = await response.parse() - assert_matches_type(AsyncDefaultFlatPagination[PhoneNumberListResponse], phone_number, path=["response"]) + assert_matches_type(AsyncDefaultFlatPagination[WhatsappPhoneResponse], phone_number, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -363,7 +363,7 @@ async def test_streaming_response_list(self, async_client: AsyncTelnyx) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" phone_number = await response.parse() - assert_matches_type(AsyncDefaultFlatPagination[PhoneNumberListResponse], phone_number, path=["response"]) + assert_matches_type(AsyncDefaultFlatPagination[WhatsappPhoneResponse], phone_number, path=["response"]) assert cast(Any, response.is_closed) is True