From f3897090482b6b2f93b36c241249286c9f8f2b39 Mon Sep 17 00:00:00 2001 From: Antoine SEIN <142824551+asein-sinch@users.noreply.github.com> Date: Wed, 18 Jun 2025 18:02:33 +0200 Subject: [PATCH 1/9] Add missing implementations for async authentication (#74) * Add missing implementations * Bump SDK version --- pyproject.toml | 2 +- sinch/__init__.py | 2 +- sinch/core/ports/http_transport.py | 46 +++++++ tests/unit/http_transport_tests.py | 187 +++++++++++++++++++++++++++++ 4 files changed, 235 insertions(+), 2 deletions(-) create mode 100644 tests/unit/http_transport_tests.py diff --git a/pyproject.toml b/pyproject.toml index 665599b0..1e3f92e2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [tool.poetry] name = "sinch" description = "Sinch SDK for Python programming language" -version = "1.1.1" +version = "1.1.2" license = "Apache 2.0" readme = "README.md" authors = [ diff --git a/sinch/__init__.py b/sinch/__init__.py index 6ee7635c..f0ac93b0 100644 --- a/sinch/__init__.py +++ b/sinch/__init__.py @@ -1,7 +1,7 @@ """ Sinch Python SDK To access Sinch resources, use the Sync or Async version of the Sinch Client. """ -__version__ = "1.1.1" +__version__ = "1.1.2" from sinch.core.clients.sinch_client_sync import SinchClient from sinch.core.clients.sinch_client_async import SinchClientAsync diff --git a/sinch/core/ports/http_transport.py b/sinch/core/ports/http_transport.py index de172311..9385b31d 100644 --- a/sinch/core/ports/http_transport.py +++ b/sinch/core/ports/http_transport.py @@ -127,6 +127,21 @@ def handle_response(self, endpoint: HTTPEndpoint, http_response: HTTPResponse): class AsyncHTTPTransport(HTTPTransport): async def authenticate(self, endpoint, request_data): + if endpoint.HTTP_AUTHENTICATION in (HTTPAuthentication.BASIC.value, HTTPAuthentication.OAUTH.value): + if ( + not self.sinch.configuration.key_id + or not self.sinch.configuration.key_secret + or not self.sinch.configuration.project_id + ): + raise ValidationException( + message=( + "key_id, key_secret and project_id are required by this API. " + "Those credentials can be obtained from Sinch portal." + ), + is_from_server=False, + response=None + ) + if endpoint.HTTP_AUTHENTICATION == HTTPAuthentication.BASIC.value: request_data.auth = httpx.BasicAuth( self.sinch.configuration.key_id, @@ -141,6 +156,37 @@ async def authenticate(self, endpoint, request_data): "Authorization": f"Bearer {token_response.access_token}", "Content-Type": "application/json" } + elif endpoint.HTTP_AUTHENTICATION == HTTPAuthentication.SIGNED.value: + if not self.sinch.configuration.application_key or not self.sinch.configuration.application_secret: + raise ValidationException( + message=( + "application key and application secret are required by this API. " + "Those credentials can be obtained from Sinch portal." + ), + is_from_server=False, + response=None + ) + signature = Signature( + self.sinch, + endpoint.HTTP_METHOD, + request_data.request_body, + endpoint.get_url_without_origin(self.sinch) + ) + request_data.headers = signature.get_http_headers_with_signature() + elif endpoint.HTTP_AUTHENTICATION == HTTPAuthentication.SMS_TOKEN.value: + if not self.sinch.configuration.sms_api_token or not self.sinch.configuration.service_plan_id: + raise ValidationException( + message=( + "sms_api_token and service_plan_id are required by this API. " + "Those credentials can be obtained from Sinch portal." + ), + is_from_server=False, + response=None + ) + request_data.headers.update({ + "Authorization": f"Bearer {self.sinch.configuration.sms_api_token}", + "Content-Type": "application/json" + }) return request_data diff --git a/tests/unit/http_transport_tests.py b/tests/unit/http_transport_tests.py new file mode 100644 index 00000000..5e096c2d --- /dev/null +++ b/tests/unit/http_transport_tests.py @@ -0,0 +1,187 @@ +import httpx +import pytest +from unittest.mock import Mock, AsyncMock +from sinch.core.enums import HTTPAuthentication +from sinch.core.exceptions import ValidationException +from sinch.core.models.http_request import HttpRequest +from sinch.core.endpoint import HTTPEndpoint +from sinch.core.models.http_response import HTTPResponse +from sinch.core.ports.http_transport import HTTPTransport, AsyncHTTPTransport + + +# Mock classes and fixtures +class MockEndpoint(HTTPEndpoint): + def __init__(self, auth_type): + self.HTTP_AUTHENTICATION = auth_type + self.HTTP_METHOD = "GET" + + def build_url(self, sinch): + return "api.sinch.com/test" + + def get_url_without_origin(self, sinch): + return "/test" + + def request_body(self): + return {} + + def build_query_params(self): + return {} + + def handle_response(self, response: HTTPResponse): + return response + + +@pytest.fixture +def mock_sinch(): + sinch = Mock() + sinch.configuration = Mock() + sinch.configuration.key_id = "test_key_id" + sinch.configuration.key_secret = "test_key_secret" + sinch.configuration.project_id = "test_project_id" + sinch.configuration.application_key = "test_app_key" + sinch.configuration.application_secret = "dGVzdF9hcHBfc2VjcmV0X2Jhc2U2NA==" + sinch.configuration.sms_api_token = "test_sms_token" + sinch.configuration.service_plan_id = "test_service_plan" + return sinch + +@pytest.fixture +def mock_sinch_async(): + sinch = Mock() + sinch.configuration = Mock() + sinch.configuration.key_id = "test_key_id" + sinch.configuration.key_secret = "test_key_secret" + sinch.configuration.project_id = "test_project_id" + sinch.configuration.application_key = "test_app_key" + sinch.configuration.application_secret = "dGVzdF9hcHBfc2VjcmV0X2Jhc2U2NA==" + sinch.configuration.sms_api_token = "test_sms_token" + sinch.configuration.service_plan_id = "test_service_plan" + + mock_auth = AsyncMock() + mock_token = Mock() + mock_token.access_token = "test_token" + mock_auth.get_auth_token.return_value = mock_token + sinch.authentication = mock_auth + + return sinch + + +@pytest.fixture +def base_request(): + return HttpRequest( + headers={}, + protocol="https://", + url="https://api.sinch.com/test", + http_method="GET", + request_body={}, + query_params={}, + auth=() + ) + +class MockHTTPTransport(HTTPTransport): + def request(self, endpoint: HTTPEndpoint) -> HTTPResponse: + # Simple mock implementation that just returns a dummy response + return HTTPResponse(status_code=200, body={}, headers={}) + +class MockAsyncHTTPTransport(AsyncHTTPTransport): + async def request(self, endpoint: HTTPEndpoint) -> HTTPResponse: + # Simple mock implementation that just returns a dummy response + return HTTPResponse(status_code=200, body={}, headers={}) + +# Synchronous Transport Tests +class TestHTTPTransport: + @pytest.mark.parametrize("auth_type", [ + HTTPAuthentication.BASIC.value, + HTTPAuthentication.OAUTH.value, + HTTPAuthentication.SIGNED.value, + HTTPAuthentication.SMS_TOKEN.value + ]) + def test_authenticate(self, mock_sinch, base_request, auth_type): + transport = MockHTTPTransport(mock_sinch) + endpoint = MockEndpoint(auth_type) + + if auth_type == HTTPAuthentication.BASIC.value: + result = transport.authenticate(endpoint, base_request) + assert result.auth == ("test_key_id", "test_key_secret") + + elif auth_type == HTTPAuthentication.OAUTH.value: + mock_sinch.authentication.get_auth_token.return_value.access_token = "test_token" + result = transport.authenticate(endpoint, base_request) + assert result.headers["Authorization"] == "Bearer test_token" + assert result.headers["Content-Type"] == "application/json" + + elif auth_type == HTTPAuthentication.SIGNED.value: + result = transport.authenticate(endpoint, base_request) + assert "x-timestamp" in result.headers + assert "Authorization" in result.headers + + elif auth_type == HTTPAuthentication.SMS_TOKEN.value: + result = transport.authenticate(endpoint, base_request) + assert result.headers["Authorization"] == "Bearer test_sms_token" + assert result.headers["Content-Type"] == "application/json" + + @pytest.mark.parametrize("auth_type,missing_creds", [ + (HTTPAuthentication.BASIC.value, {"key_id": None}), + (HTTPAuthentication.OAUTH.value, {"key_secret": None}), + (HTTPAuthentication.SIGNED.value, {"application_key": None}), + (HTTPAuthentication.SMS_TOKEN.value, {"sms_api_token": None}) + ]) + def test_authenticate_missing_credentials(self, mock_sinch, base_request, auth_type, missing_creds): + transport = MockHTTPTransport(mock_sinch) + endpoint = MockEndpoint(auth_type) + + for cred, value in missing_creds.items(): + setattr(mock_sinch.configuration, cred, value) + + with pytest.raises(ValidationException): + transport.authenticate(endpoint, base_request) + +# Async Transport Tests +class TestAsyncHTTPTransport: + @pytest.mark.asyncio + @pytest.mark.parametrize("auth_type", [ + HTTPAuthentication.BASIC.value, + HTTPAuthentication.OAUTH.value, + HTTPAuthentication.SIGNED.value, + HTTPAuthentication.SMS_TOKEN.value + ]) + async def test_authenticate(self, mock_sinch_async, base_request, auth_type): + transport = MockAsyncHTTPTransport(mock_sinch_async) + endpoint = MockEndpoint(auth_type) + + if auth_type == HTTPAuthentication.BASIC.value: + result = await transport.authenticate(endpoint, base_request) + assert isinstance(result.auth, httpx.BasicAuth) + assert result.auth._auth_header == "Basic dGVzdF9rZXlfaWQ6dGVzdF9rZXlfc2VjcmV0" + + elif auth_type == HTTPAuthentication.OAUTH.value: + mock_sinch_async.authentication.get_auth_token.return_value.access_token = "test_token" + result = await transport.authenticate(endpoint, base_request) + assert result.headers["Authorization"] == "Bearer test_token" + assert result.headers["Content-Type"] == "application/json" + + elif auth_type == HTTPAuthentication.SIGNED.value: + result = await transport.authenticate(endpoint, base_request) + assert "x-timestamp" in result.headers + assert "Authorization" in result.headers + + elif auth_type == HTTPAuthentication.SMS_TOKEN.value: + result = await transport.authenticate(endpoint, base_request) + assert result.headers["Authorization"] == "Bearer test_sms_token" + assert result.headers["Content-Type"] == "application/json" + + @pytest.mark.asyncio + @pytest.mark.parametrize("auth_type,missing_creds", [ + (HTTPAuthentication.BASIC.value, {"key_id": None}), + (HTTPAuthentication.OAUTH.value, {"key_secret": None}), + (HTTPAuthentication.SIGNED.value, {"application_key": None}), + (HTTPAuthentication.SMS_TOKEN.value, {"sms_api_token": None}) + ]) + async def test_authenticate_missing_credentials(self, mock_sinch_async, base_request, auth_type, missing_creds): + transport = MockAsyncHTTPTransport(mock_sinch_async) + endpoint = MockEndpoint(auth_type) + + for cred, value in missing_creds.items(): + setattr(mock_sinch_async.configuration, cred, value) + + with pytest.raises(ValidationException): + await transport.authenticate(endpoint, base_request) \ No newline at end of file From 863bece71833f68a0b62540e006c9afe54e1f4be Mon Sep 17 00:00:00 2001 From: Antoine SEIN <142824551+asein-sinch@users.noreply.github.com> Date: Thu, 11 Sep 2025 11:43:44 +0200 Subject: [PATCH 2/9] Fix DTMF options for conference call (#79) --- pyproject.toml | 2 +- sinch/__init__.py | 2 +- .../voice/endpoints/callouts/callout.py | 6 +- .../domains/voice/test_callout_conference.py | 77 +++++++++++++++++++ 4 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 tests/unit/domains/voice/test_callout_conference.py diff --git a/pyproject.toml b/pyproject.toml index 1e3f92e2..6a59c2b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [tool.poetry] name = "sinch" description = "Sinch SDK for Python programming language" -version = "1.1.2" +version = "1.1.3" license = "Apache 2.0" readme = "README.md" authors = [ diff --git a/sinch/__init__.py b/sinch/__init__.py index f0ac93b0..a9dd613d 100644 --- a/sinch/__init__.py +++ b/sinch/__init__.py @@ -1,7 +1,7 @@ """ Sinch Python SDK To access Sinch resources, use the Sync or Async version of the Sinch Client. """ -__version__ = "1.1.2" +__version__ = "1.1.3" from sinch.core.clients.sinch_client_sync import SinchClient from sinch.core.clients.sinch_client_async import SinchClientAsync diff --git a/sinch/domains/voice/endpoints/callouts/callout.py b/sinch/domains/voice/endpoints/callouts/callout.py index 324e7698..ef889a05 100644 --- a/sinch/domains/voice/endpoints/callouts/callout.py +++ b/sinch/domains/voice/endpoints/callouts/callout.py @@ -36,13 +36,13 @@ def request_body(self): dtmf_options = {} if self.request_data.conferenceDtmfOptions["mode"]: - dtmf_options["mode"] = self.request_data.get["conferenceDtmfOptions"]["mode"] + dtmf_options["mode"] = self.request_data.conferenceDtmfOptions["mode"] if self.request_data.conferenceDtmfOptions["timeout_mills"]: - dtmf_options["timeoutMills"] = self.request_data.get["conferenceDtmfOptions"]["timeout_mills"] + dtmf_options["timeoutMills"] = self.request_data.conferenceDtmfOptions["timeout_mills"] if self.request_data.conferenceDtmfOptions["max_digits"]: - dtmf_options["maxDigits"] = self.request_data.get["conferenceDtmfOptions"]["max_digits"] + dtmf_options["maxDigits"] = self.request_data.conferenceDtmfOptions["max_digits"] self.request_data.conferenceDtmfOptions = dtmf_options diff --git a/tests/unit/domains/voice/test_callout_conference.py b/tests/unit/domains/voice/test_callout_conference.py new file mode 100644 index 00000000..9ea2169c --- /dev/null +++ b/tests/unit/domains/voice/test_callout_conference.py @@ -0,0 +1,77 @@ +import json +import pytest +from sinch.domains.voice.enums import CalloutMethod + +from sinch.domains.voice.endpoints.callouts.callout import CalloutEndpoint + +from sinch.domains.voice.models.callouts.requests import ConferenceVoiceCalloutRequest + + +@pytest.fixture +def request_data(): + return ConferenceVoiceCalloutRequest( + destination={ + "type": "number", + "endpoint": "+33612345678", + }, + cli="", + greeting='Welcome', + conferenceId="123456", + conferenceDtmfOptions={ + "mode": "forward", + "max_digits": 2, + "timeout_mills": 2500 + }, + dtmf="dtmf", + conference="conference", + maxDuration=10, + enableAce=True, + enableDice=True, + enablePie=True, + locale="locale", + mohClass="moh_class", + custom="custom", + domain="pstn" + ) + +@pytest.fixture +def endpoint(request_data): + return CalloutEndpoint(request_data, CalloutMethod.CONFERENCE.value) + +@pytest.fixture +def mock_response_body(): + expected_body = { + "method" : "conferenceCallout", + "conferenceCallout" : { + "destination" : { + "type" : "number", + "endpoint" : "+33612345678" + }, + "conferenceId" : "123456", + "cli" : "", + "conferenceDtmfOptions" : { + "mode" : "forward", + "timeoutMills" : 2500, + "maxDigits" : 2 + }, + "dtmf" : "dtmf", + "conference" : "conference", + "maxDuration" : 10, + "enableAce" : True, + "enableDice" : True, + "enablePie" : True, + "locale" : "locale", + "greeting" : "Welcome", + "mohClass" : "moh_class", + "custom" : "custom", + "domain" : "pstn" + } + } + return json.dumps(expected_body) + +def test_handle_response(endpoint, mock_response_body): + """ + Check if response is handled and mapped to the appropriate fields correctly. + """ + request_body = endpoint.request_body() + assert request_body == mock_response_body From b2145bdae6158d0294a7c549c87a6d82871307cf Mon Sep 17 00:00:00 2001 From: Vincent Date: Thu, 23 Oct 2025 02:26:37 -0600 Subject: [PATCH 3/9] Add python 3.13 and 3.14 spec (#86) Co-authored-by: Vincent Davis --- .github/workflows/run-tests.yml | 2 +- README.md | 4 +++- pyproject.toml | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 92ab75e3..828691a7 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -24,7 +24,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] steps: - uses: actions/checkout@v3 diff --git a/README.md b/README.md index 733c0c0a..5b7c40c4 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ [![Python 3.10](https://img.shields.io/badge/python-3.10-blue.svg)](https://www.python.org/downloads/release/python-3100/) [![Python 3.11](https://img.shields.io/badge/python-3.11-blue.svg)](https://www.python.org/downloads/release/python-3110/) [![Python 3.12](https://img.shields.io/badge/python-3.12-blue.svg)](https://www.python.org/downloads/release/python-3120/) +[![Python 3.13](https://img.shields.io/badge/python-3.13-blue.svg)](https://www.python.org/downloads/release/python-3130/) +[![Python 3.14](https://img.shields.io/badge/python-3.14-blue.svg)](https://www.python.org/downloads/release/python-3140/) @@ -24,7 +26,7 @@ For more information on the Sinch APIs on which this SDK is based, refer to the ## Prerequisites -- Python in one of the supported versions - 3.9, 3.10, 3.11, 3.12 +- Python in one of the supported versions - 3.9, 3.10, 3.11, 3.12, 3.13, 3.14 - pip - Sinch account diff --git a/pyproject.toml b/pyproject.toml index 6a59c2b5..eae40698 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,8 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.14", + "Programming Language :: Python :: 3.14", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Communications :: Telephony", From e16baa4894ed3520eb5fc23593d57390c7738257 Mon Sep 17 00:00:00 2001 From: Jessica Matsuoka Date: Thu, 23 Oct 2025 15:19:13 +0200 Subject: [PATCH 4/9] relese(ci): Add Python 3.13 and 3.14 support (#89) Co-authored by: @vincentdavis --- pyproject.toml | 4 ++-- sinch/__init__.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index eae40698..44d69345 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [tool.poetry] name = "sinch" description = "Sinch SDK for Python programming language" -version = "1.1.3" +version = "1.1.4" license = "Apache 2.0" readme = "README.md" authors = [ @@ -17,7 +17,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.14", + "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Software Development :: Libraries :: Python Modules", diff --git a/sinch/__init__.py b/sinch/__init__.py index a9dd613d..769e4e96 100644 --- a/sinch/__init__.py +++ b/sinch/__init__.py @@ -1,7 +1,7 @@ """ Sinch Python SDK To access Sinch resources, use the Sync or Async version of the Sinch Client. """ -__version__ = "1.1.3" +__version__ = "1.1.4" from sinch.core.clients.sinch_client_sync import SinchClient from sinch.core.clients.sinch_client_async import SinchClientAsync From 7210e4f5bdfee84809039e18b312f8f680f5e7f1 Mon Sep 17 00:00:00 2001 From: Jessica Matsuoka Date: Tue, 25 Nov 2025 10:15:39 +0100 Subject: [PATCH 5/9] chore: add CODEOWNERS (#100) --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 585690ea..10b70ef9 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,2 +1,2 @@ # https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners -* @matsk-sinch @Dovchik @krogers0607 @asein-sinch @JPPortier \ No newline at end of file +* @matsk-sinch @asein-sinch @JPPortier @rpredescu-sinch \ No newline at end of file From f56daa5cd991c8253dde492eeef6097f6cf3fab6 Mon Sep 17 00:00:00 2001 From: Jessica Matsuoka Date: Wed, 25 Mar 2026 16:29:00 +0100 Subject: [PATCH 6/9] chore: update CI --- .github/workflows/ci.yml | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8e75080a..0534969d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,8 +2,6 @@ name: Test Python SDK on: [ push ] env: - APPLICATION_KEY: ${{ secrets.APPLICATION_KEY }} - APPLICATION_SECRET: ${{ secrets.APPLICATION_SECRET }} AUTH_ORIGIN: ${{ secrets.AUTH_ORIGIN }} CONVERSATION_ORIGIN: ${{ secrets.CONVERSATION_ORIGIN }} DISABLE_SSL: ${{ secrets.DISABLE_SSL }} @@ -24,9 +22,9 @@ jobs: python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install dependencies @@ -68,22 +66,17 @@ jobs: python -m coverage report --skip-empty - name: Checkout sinch-sdk-mockserver repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: sinch/sinch-sdk-mockserver token: ${{ secrets.PAT_CI }} fetch-depth: 0 path: sinch-sdk-mockserver - - name: Install Docker Compose - run: | - sudo apt-get update - sudo apt-get install -y docker-compose - - name: Start mock servers with Docker Compose run: | cd sinch-sdk-mockserver - docker-compose up -d + docker compose up -d - name: Copy feature files run: | @@ -110,5 +103,3 @@ jobs: python -m behave tests/e2e/sms/features python -m behave tests/e2e/conversation/features python -m behave tests/e2e/number-lookup/features - - \ No newline at end of file From 1d1a7814b77d202201f0e1f97f399342fac1ea04 Mon Sep 17 00:00:00 2001 From: Jessica Matsuoka Date: Wed, 25 Mar 2026 16:31:03 +0100 Subject: [PATCH 7/9] update documentation --- MIGRATION_GUIDE.md | 21 +++++++++++++-------- README.md | 38 +++++++++++++++++--------------------- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index b2d5dc74..19148549 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -8,6 +8,8 @@ This guide lists all removed classes and interfaces from V1 and how to migrate t > **Note:** Voice and Verification are not yet covered by the new V2 APIs. Support will be added in future releases. +--- + ## Client Initialization ### Overview @@ -62,6 +64,8 @@ token_client = SinchClient( sinch_client.configuration.sms_region = "eu" ``` +--- + ### Conversation Region **In V1:** @@ -95,6 +99,8 @@ sinch_client = SinchClient( sinch_client.configuration.conversation_region = "eu" ``` +--- + ### [`Conversation`](https://github.com/sinch/sinch-sdk-python/tree/main/sinch/domains/conversation) #### Replacement models @@ -123,8 +129,8 @@ The Conversation domain API access remains `sinch_client.conversation`; message | `send()` with `SendConversationMessageRequest` | Use convenience methods: `send_text_message()`, `send_card_message()`, `send_carousel_message()`, `send_choice_message()`, `send_contact_info_message()`, `send_list_message()`, `send_location_message()`, `send_media_message()`, `send_template_message()`
Or `send()` with `app_id`, `message` (dict or `SendMessageRequestBodyDict`), and either `contact_id` or `recipient_identities` | | `get()` with `GetConversationMessageRequest` | `get()` with `message_id: str` parameter | | `delete()` with `DeleteConversationMessageRequest` | `delete()` with `message_id: str` parameter | -| `list()` with `ListConversationMessagesRequest` | In Progress | -| — | **New in V2:** `update()` with `message_id`, `metadata`, and optional `messages_source`| +| `list()` with `ListConversationMessagesRequest` | `list()` with the same fields as keyword arguments (see models table above). V2 adds optional `channel_identity`, `start_time`, `end_time`, `channel`, `direction`. Returns **`Paginator[ConversationMessageResponse]`**: use `.content()` for messages on the current page, `.next_page()` to load the next page, or `.iterator()` to walk every message across all pages. | +| — | **New in V2:** `update()` with `message_id`, `metadata`, and optional `messages_source` | ##### Replacement APIs / attributes @@ -158,7 +164,7 @@ event = handler.parse_event(request_body) The Conversation HTTP API still expects the JSON field **`callback_url`**. In V2, use the Python parameter / model field `event_destination_target`; it is serialized as `callback_url` on the wire (same pattern as other domains, e.g. SMS). -
+--- ### [`SMS`](https://github.com/sinch/sinch-sdk-python/tree/main/sinch/domains/sms) @@ -200,6 +206,7 @@ The Conversation HTTP API still expects the JSON field **`callback_url`**. In V2 #### Replacement APIs The SMS domain API access remains the same: `sinch.sms.batches` and `sinch.sms.delivery_reports`. However, the underlying models and method signatures have changed. + Note that `sinch.sms.groups` and `sinch.sms.inbounds` are not supported yet and will be available in future minor versions. ##### Batches API @@ -213,17 +220,17 @@ Note that `sinch.sms.groups` and `sinch.sms.inbounds` are not supported yet and | `update()` with `UpdateBatchRequest` | Use convenience methods: `update_sms()`, `update_binary()`, `update_mms()`
Or `update()` with `UpdateBatchMessageRequest` (Union of `UpdateTextRequestWithBatchId`, `UpdateBinaryRequestWithBatchId`, `UpdateMediaRequestWithBatchId`) | | `replace()` with `ReplaceBatchRequest` | Use convenience methods: `replace_sms()`, `replace_binary()`, `replace_mms()`
Or `replace()` with `ReplaceBatchRequest` (Union of `ReplaceTextRequest`, `ReplaceBinaryRequest`, `ReplaceMediaRequest`) | -
+--- ##### Delivery Reports API | Old method | New method in `sms.delivery_reports` | |------------|-------------------------------------| -| `list()` with `ListSMSDeliveryReportsRequest` | `list()` the parameters `start_date` and `end_date` now accepts both `str` and `datetime` | +| `list()` with `ListSMSDeliveryReportsRequest` | `list()` the parameters `start_date` and `end_date` now accepts both `str` and `datetime` | | `get_for_batch()` with `GetSMSDeliveryReportForBatchRequest` | `get()` with `batch_id: str` and optional parameters: `report_type`, `status`, `code`, `client_reference` | | `get_for_number()` with `GetSMSDeliveryReportForNumberRequest` | `get_for_number()` with `batch_id: str` and `recipient: str` parameters | -
+--- ### [`Numbers` (Virtual Numbers)](https://github.com/sinch/sinch-sdk-python/tree/main/sinch/domains/numbers) @@ -271,7 +278,6 @@ sinch_client.numbers.event_destinations.update(hmac_secret="your_hmac_secret") To obtain a Numbers Sinch Events handler: `sinch_client.numbers.sinch_events(callback_secret)` returns a `SinchEvents` instance; `handler.parse_event(request_body)` returns a `NumberSinchEvent`. - ```python # New from sinch.domains.numbers.sinch_events.v1.events import NumberSinchEvent @@ -286,7 +292,6 @@ event = handler.parse_event(request_body) # event is a NumberSinchEvent | **Methods that accept the parameter** | Only `numbers.available.rent_any(..., callback_url=...)` | `numbers.rent(...)`, `numbers.rent_any(...)`, and `numbers.update(...)` accept `event_destination_target` | | **Parameter name** | `callback_url` | `event_destination_target` | - ##### Replacement request/response attributes | Old | New | diff --git a/README.md b/README.md index 683d16eb..7d72bfc8 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ For more information on the Sinch APIs on which this SDK is based, refer to the - [Prerequisites](#prerequisites) - [Installation](#installation) - [Getting started](#getting-started) -- [Logging]() +- [Logging](#logging) ## Prerequisites @@ -79,6 +79,10 @@ sinch_client = SinchClient( ) ``` +### SMS and Conversation regions (V2) + +You must set `sms_region` before using the SMS API and `conversation_region` before using the Conversation API—either in the `SinchClient(...)` constructor or on `sinch_client.configuration` before the first call to that product. See [MIGRATION_GUIDE.md](MIGRATION_GUIDE.md) for examples. + ## Logging Logging configuration for this SDK utilizes following hierarchy: @@ -86,34 +90,26 @@ Logging configuration for this SDK utilizes following hierarchy: 2. If `logger_name` configurable was provided, SDK will use logger related to that name. For example: `myapp.sinch` will inherit configuration from the `myapp` logger. 3. If `logger` (logger instance) configurable was provided, SDK will use that particular logger for all its logging operations. -If all logging returned by this SDK needs to be disabled, usage of `NullHanlder` provided by the standard `logging` module is advised. +If all logging returned by this SDK needs to be disabled, usage of `NullHandler` provided by the standard `logging` module is advised. ## Sample apps -Usage example of the `numbers` domain: +Usage example of the Numbers API via [`VirtualNumbers`](sinch/domains/numbers/virtual_numbers.py) on the client (`sinch_client.numbers`)—`list()` returns your project’s active virtual numbers: ```python -available_numbers = sinch_client.numbers.available.list( +paginator = sinch_client.numbers.list( region_code="US", - number_type="LOCAL" + number_type="LOCAL", ) +for active_number in paginator.iterator(): + print(active_number) ``` -Returned values are represented as Python `dataclasses`: -```python -ListAvailableNumbersResponse( - available_numbers=[ - Number( - phone_number='+17862045855', - region_code='US', - type='LOCAL', - capability=['SMS', 'VOICE'], - setup_price={'currency_code': 'EUR', 'amount': '0.80'}, - monthly_price={'currency_code': 'EUR', 'amount': '0.80'} - ... -``` +Returned values are [Pydantic](https://docs.pydantic.dev/) model instances (for example [`ActiveNumber`](sinch/domains/numbers/models/v1/response/active_number.py)), including fields such as `phone_number`, `region_code`, `type`, and `capabilities`. + +More examples live under [examples/snippets](examples/snippets) on the `main` branch. ### Handling exceptions @@ -125,9 +121,9 @@ Example for Numbers API: from sinch.domains.numbers.api.v1.exceptions import NumbersException try: - nums = sinch_client.numbers.available.list( + paginator = sinch_client.numbers.list( region_code="US", - number_type="LOCAL" + number_type="LOCAL", ) except NumbersException as err: pass @@ -163,4 +159,4 @@ The transport must be a synchronous implementation. ## License -This project is licensed under the Apache License. See the [LICENSE](license.md) file for the license text. +This project is licensed under the Apache License. See the [LICENSE](LICENSE) file for the license text. From 2982fc118b17faa8550e052f6f52c0d4a14eedeb Mon Sep 17 00:00:00 2001 From: Jessica Matsuoka Date: Wed, 25 Mar 2026 16:53:23 +0100 Subject: [PATCH 8/9] update examples --- examples/sinch_events/pyproject.toml | 3 +-- examples/snippets/README.md | 2 +- .../conversation/messages/delete/snippet.py | 3 +-- .../conversation/messages/get/snippet.py | 3 +-- .../conversation/messages/list/snippet.py | 3 +-- .../snippet.py | 5 ++--- .../conversation/messages/send/snippet.py | 18 ++++++++++-------- .../messages/send_card_message/snippet.py | 3 +-- .../messages/send_carousel_message/snippet.py | 3 +-- .../messages/send_choice_message/snippet.py | 3 +-- .../send_contact_info_message/snippet.py | 3 +-- .../messages/send_list_message/snippet.py | 3 +-- .../messages/send_location_message/snippet.py | 3 +-- .../messages/send_media_message/snippet.py | 3 +-- .../messages/send_template_message/snippet.py | 3 +-- .../messages/send_text_message/snippet.py | 3 +-- .../conversation/messages/update/snippet.py | 7 ++++--- .../snippets/number_lookup/lookup/snippet.py | 7 +++---- .../numbers/active_numbers/get/snippet.py | 7 ++++--- .../numbers/active_numbers/list/snippet.py | 3 +-- .../active_numbers/list_auto/snippet.py | 3 +-- .../numbers/active_numbers/release/snippet.py | 7 ++++--- .../numbers/active_numbers/update/snippet.py | 13 +++++++------ .../check_availability/snippet.py | 5 +++-- .../numbers/available_numbers/rent/snippet.py | 13 +++++++------ .../available_numbers/rent_any/snippet.py | 13 ++++++++----- .../search_for_available_numbers/snippet.py | 3 +-- .../numbers/available_regions/list/snippet.py | 3 +-- .../numbers/event_destinations/get/snippet.py | 3 +-- .../event_destinations/update/snippet.py | 7 ++++--- .../snippets/sms/batches/cancel/snippet.py | 4 ++-- .../sms/batches/dry_run_binary/snippet.py | 3 +-- .../sms/batches/dry_run_mms/snippet.py | 3 +-- .../sms/batches/dry_run_sms/snippet.py | 3 +-- examples/snippets/sms/batches/get/snippet.py | 4 ++-- examples/snippets/sms/batches/list/snippet.py | 3 +-- .../sms/batches/replace_binary/snippet.py | 3 +-- .../sms/batches/replace_mms/snippet.py | 3 +-- .../sms/batches/replace_sms/snippet.py | 3 +-- .../sms/batches/send_binary/snippet.py | 3 +-- .../batches/send_delivery_feedback/snippet.py | 3 +-- .../snippets/sms/batches/send_mms/snippet.py | 3 +-- .../snippets/sms/batches/send_sms/snippet.py | 3 +-- .../sms/batches/update_binary/snippet.py | 3 +-- .../snippets/sms/batches/update_mms/snippet.py | 3 +-- .../snippets/sms/batches/update_sms/snippet.py | 3 +-- .../sms/delivery_reports/get/snippet.py | 4 ++-- .../delivery_reports/get_for_number/snippet.py | 3 +-- .../sms/delivery_reports/list/snippet.py | 3 +-- 49 files changed, 97 insertions(+), 121 deletions(-) diff --git a/examples/sinch_events/pyproject.toml b/examples/sinch_events/pyproject.toml index 206757a7..4fb38639 100644 --- a/examples/sinch_events/pyproject.toml +++ b/examples/sinch_events/pyproject.toml @@ -9,8 +9,7 @@ package-mode = false python = "^3.9" python-dotenv = "^1.0.0" flask = "^3.0.0" -# TODO: Uncomment once v2.0 is released -# sinch = "^2.0.0" +sinch = "^2.0.0" [build-system] requires = ["poetry-core"] diff --git a/examples/snippets/README.md b/examples/snippets/README.md index 35bb6550..b5dd5e2f 100644 --- a/examples/snippets/README.md +++ b/examples/snippets/README.md @@ -57,5 +57,5 @@ All available code snippets are located in subdirectories, structured by feature To execute a specific snippet, navigate to the appropriate subdirectory and run: ```shell -python run python snippet.py +python snippet.py ``` \ No newline at end of file diff --git a/examples/snippets/conversation/messages/delete/snippet.py b/examples/snippets/conversation/messages/delete/snippet.py index c520eb7c..b67d1a9f 100644 --- a/examples/snippets/conversation/messages/delete/snippet.py +++ b/examples/snippets/conversation/messages/delete/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/conversation/messages/get/snippet.py b/examples/snippets/conversation/messages/get/snippet.py index 4c3d343c..7e9ff953 100644 --- a/examples/snippets/conversation/messages/get/snippet.py +++ b/examples/snippets/conversation/messages/get/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/conversation/messages/list/snippet.py b/examples/snippets/conversation/messages/list/snippet.py index ab68afb3..a10dd293 100644 --- a/examples/snippets/conversation/messages/list/snippet.py +++ b/examples/snippets/conversation/messages/list/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/conversation/messages/list_last_messages_by_channel_identity/snippet.py b/examples/snippets/conversation/messages/list_last_messages_by_channel_identity/snippet.py index 66300d6b..7cde3ee9 100644 --- a/examples/snippets/conversation/messages/list_last_messages_by_channel_identity/snippet.py +++ b/examples/snippets/conversation/messages/list_last_messages_by_channel_identity/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os @@ -18,7 +17,7 @@ conversation_region=os.environ.get("SINCH_CONVERSATION_REGION") or "MY_CONVERSATION_REGION" ) -# Channel identities to fetch the last message +# The channel identities to fetch the last message for channel_identities = ["CHANNEL_IDENTITY_1", "CHANNEL_IDENTITY_2"] messages = sinch_client.conversation.messages.list_last_messages_by_channel_identity( diff --git a/examples/snippets/conversation/messages/send/snippet.py b/examples/snippets/conversation/messages/send/snippet.py index 970c9c99..1798eb99 100644 --- a/examples/snippets/conversation/messages/send/snippet.py +++ b/examples/snippets/conversation/messages/send/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os @@ -28,14 +27,17 @@ } ] +# The conversation message payload to send +message = { + "text_message": { + "text": "[Python SDK: Conversation Message] Sample text message", + }, +} + response = sinch_client.conversation.messages.send( app_id=app_id, - message={ - "text_message": { - "text": "[Python SDK: Conversation Message] Sample text message" - } - }, - recipient_identities=recipient_identities + message=message, + recipient_identities=recipient_identities, ) print(f"Successfully sent message.\n{response}") diff --git a/examples/snippets/conversation/messages/send_card_message/snippet.py b/examples/snippets/conversation/messages/send_card_message/snippet.py index 5300eaf2..03a6496c 100644 --- a/examples/snippets/conversation/messages/send_card_message/snippet.py +++ b/examples/snippets/conversation/messages/send_card_message/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/conversation/messages/send_carousel_message/snippet.py b/examples/snippets/conversation/messages/send_carousel_message/snippet.py index bb8ecb4f..92f5f7ec 100644 --- a/examples/snippets/conversation/messages/send_carousel_message/snippet.py +++ b/examples/snippets/conversation/messages/send_carousel_message/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/conversation/messages/send_choice_message/snippet.py b/examples/snippets/conversation/messages/send_choice_message/snippet.py index 315e13d4..5db53bfe 100644 --- a/examples/snippets/conversation/messages/send_choice_message/snippet.py +++ b/examples/snippets/conversation/messages/send_choice_message/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/conversation/messages/send_contact_info_message/snippet.py b/examples/snippets/conversation/messages/send_contact_info_message/snippet.py index 70f84c57..4f3cffa4 100644 --- a/examples/snippets/conversation/messages/send_contact_info_message/snippet.py +++ b/examples/snippets/conversation/messages/send_contact_info_message/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/conversation/messages/send_list_message/snippet.py b/examples/snippets/conversation/messages/send_list_message/snippet.py index 3b7010ac..8b807aa1 100644 --- a/examples/snippets/conversation/messages/send_list_message/snippet.py +++ b/examples/snippets/conversation/messages/send_list_message/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/conversation/messages/send_location_message/snippet.py b/examples/snippets/conversation/messages/send_location_message/snippet.py index 451d0d83..0b8b3426 100644 --- a/examples/snippets/conversation/messages/send_location_message/snippet.py +++ b/examples/snippets/conversation/messages/send_location_message/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/conversation/messages/send_media_message/snippet.py b/examples/snippets/conversation/messages/send_media_message/snippet.py index df7aa970..ca977797 100644 --- a/examples/snippets/conversation/messages/send_media_message/snippet.py +++ b/examples/snippets/conversation/messages/send_media_message/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/conversation/messages/send_template_message/snippet.py b/examples/snippets/conversation/messages/send_template_message/snippet.py index cb604a74..c6b19843 100644 --- a/examples/snippets/conversation/messages/send_template_message/snippet.py +++ b/examples/snippets/conversation/messages/send_template_message/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/conversation/messages/send_text_message/snippet.py b/examples/snippets/conversation/messages/send_text_message/snippet.py index 6a5bebbe..fa6431c5 100644 --- a/examples/snippets/conversation/messages/send_text_message/snippet.py +++ b/examples/snippets/conversation/messages/send_text_message/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/conversation/messages/update/snippet.py b/examples/snippets/conversation/messages/update/snippet.py index 72d31d32..b6f89a45 100644 --- a/examples/snippets/conversation/messages/update/snippet.py +++ b/examples/snippets/conversation/messages/update/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os @@ -20,10 +19,12 @@ # The ID of the message to update message_id = "MESSAGE_ID" +# The metadata string to set on the message +metadata = "MESSAGE_METADATA" response = sinch_client.conversation.messages.update( message_id=message_id, - metadata="metadata value set from Python SDK snippet" + metadata=metadata, ) print(f"Updated message:\n{response}") diff --git a/examples/snippets/number_lookup/lookup/snippet.py b/examples/snippets/number_lookup/lookup/snippet.py index 35b63e3b..98eec221 100644 --- a/examples/snippets/number_lookup/lookup/snippet.py +++ b/examples/snippets/number_lookup/lookup/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os @@ -17,8 +16,8 @@ key_secret=os.environ.get("SINCH_KEY_SECRET") or "MY_KEY_SECRET", ) -# The phone number to lookup in E.164 format (e.g., +1234567890) -phone_number = "PHONE_NUMBER_TO_LOOKUP" +# The phone number to look up in E.164 format (e.g. +1234567890) +phone_number = "PHONE_NUMBER" response = sinch_client.number_lookup.lookup(number=phone_number) diff --git a/examples/snippets/numbers/active_numbers/get/snippet.py b/examples/snippets/numbers/active_numbers/get/snippet.py index 37516175..5787fd90 100644 --- a/examples/snippets/numbers/active_numbers/get/snippet.py +++ b/examples/snippets/numbers/active_numbers/get/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os @@ -17,7 +16,9 @@ key_secret=os.environ.get("SINCH_KEY_SECRET") or "MY_KEY_SECRET" ) -phone_number = os.environ.get("SINCH_PHONE_NUMBER") or "MY_SINCH_PHONE_NUMBER" +# The active phone number to retrieve details for in E.164 format +phone_number = os.environ.get("SINCH_PHONE_NUMBER") or "MY_PHONE_NUMBER" + response = sinch_client.numbers.get(phone_number=phone_number) print(f"Rented number details:\n{response}") diff --git a/examples/snippets/numbers/active_numbers/list/snippet.py b/examples/snippets/numbers/active_numbers/list/snippet.py index 6ad2d486..65cfc4f7 100644 --- a/examples/snippets/numbers/active_numbers/list/snippet.py +++ b/examples/snippets/numbers/active_numbers/list/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/numbers/active_numbers/list_auto/snippet.py b/examples/snippets/numbers/active_numbers/list_auto/snippet.py index c35b1294..ff180cd6 100644 --- a/examples/snippets/numbers/active_numbers/list_auto/snippet.py +++ b/examples/snippets/numbers/active_numbers/list_auto/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/numbers/active_numbers/release/snippet.py b/examples/snippets/numbers/active_numbers/release/snippet.py index c0c56489..93accd26 100644 --- a/examples/snippets/numbers/active_numbers/release/snippet.py +++ b/examples/snippets/numbers/active_numbers/release/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os @@ -17,7 +16,9 @@ key_secret=os.environ.get("SINCH_KEY_SECRET") or "MY_KEY_SECRET" ) -phone_number = os.environ.get("SINCH_PHONE_NUMBER") or "MY_SINCH_PHONE_NUMBER" +# The phone number to release in E.164 format +phone_number = os.environ.get("SINCH_PHONE_NUMBER") or "MY_PHONE_NUMBER" + released_number = sinch_client.numbers.release( phone_number=phone_number ) diff --git a/examples/snippets/numbers/active_numbers/update/snippet.py b/examples/snippets/numbers/active_numbers/update/snippet.py index 253fea5c..4d9902ad 100644 --- a/examples/snippets/numbers/active_numbers/update/snippet.py +++ b/examples/snippets/numbers/active_numbers/update/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os @@ -17,12 +16,14 @@ key_secret=os.environ.get("SINCH_KEY_SECRET") or "MY_KEY_SECRET" ) -phone_number_to_update = os.environ.get("SINCH_PHONE_NUMBER") or "MY_SINCH_PHONE_NUMBER" -updated_display_name = "Updated DISPLAY_NAME" +# The phone number to update in E.164 format +phone_number = os.environ.get("SINCH_PHONE_NUMBER") or "MY_PHONE_NUMBER" +# The display name to set for the number +display_name = "DISPLAY_NAME" response = sinch_client.numbers.update( - phone_number=phone_number_to_update, - display_name=updated_display_name + phone_number=phone_number, + display_name=display_name, ) print("Updated Number:\n", response) diff --git a/examples/snippets/numbers/available_numbers/check_availability/snippet.py b/examples/snippets/numbers/available_numbers/check_availability/snippet.py index 6ad8ab89..3cce5738 100644 --- a/examples/snippets/numbers/available_numbers/check_availability/snippet.py +++ b/examples/snippets/numbers/available_numbers/check_availability/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os @@ -17,7 +16,9 @@ key_secret=os.environ.get("SINCH_KEY_SECRET") or "MY_KEY_SECRET" ) +# The phone number to check in E.164 format phone_number = "PHONE_NUMBER" + response = sinch_client.numbers.check_availability( phone_number=phone_number ) diff --git a/examples/snippets/numbers/available_numbers/rent/snippet.py b/examples/snippets/numbers/available_numbers/rent/snippet.py index 82f0f59f..f369d9fe 100644 --- a/examples/snippets/numbers/available_numbers/rent/snippet.py +++ b/examples/snippets/numbers/available_numbers/rent/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os @@ -18,14 +17,16 @@ key_secret=os.environ.get("SINCH_KEY_SECRET") or "MY_KEY_SECRET" ) -phone_number_to_be_rented = "AVAILABLE_PHONE_NUMBER_TO_BE_RENTED" -service_plan_id_to_associate_with_the_number = os.environ.get("SINCH_SERVICE_PLAN_ID") or "MY_SERVICE_PLAN_ID" +# The available phone number to rent in E.164 format +phone_number = "PHONE_NUMBER" +# The service plan ID to associate with the phone number +service_plan_id = os.environ.get("SINCH_SERVICE_PLAN_ID") or "MY_SERVICE_PLAN_ID" sms_configuration: SmsConfigurationDict = { - "service_plan_id": service_plan_id_to_associate_with_the_number + "service_plan_id": service_plan_id, } rented_number = sinch_client.numbers.rent( - phone_number=phone_number_to_be_rented, + phone_number=phone_number, sms_configuration=sms_configuration ) print("Rented Number:\n", rented_number) diff --git a/examples/snippets/numbers/available_numbers/rent_any/snippet.py b/examples/snippets/numbers/available_numbers/rent_any/snippet.py index a7ce7a60..cc55923a 100644 --- a/examples/snippets/numbers/available_numbers/rent_any/snippet.py +++ b/examples/snippets/numbers/available_numbers/rent_any/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os @@ -18,16 +17,20 @@ key_secret=os.environ.get("SINCH_KEY_SECRET") or "MY_KEY_SECRET" ) -service_plan_id_to_associate_with_the_number = os.environ.get("SINCH_SERVICE_PLAN_ID") or "MY_SERVICE_PLAN_ID" +# The service plan ID to associate with the phone number +service_plan_id = os.environ.get("SINCH_SERVICE_PLAN_ID") or "MY_SERVICE_PLAN_ID" sms_configuration: SmsConfigurationDict = { - "service_plan_id": service_plan_id_to_associate_with_the_number + "service_plan_id": service_plan_id, } +# The URL to receive the notifications about provisioning events +event_destination_target = "CALLBACK_URL" response = sinch_client.numbers.rent_any( region_code="US", number_type="LOCAL", capabilities=["SMS", "VOICE"], - sms_configuration=sms_configuration + sms_configuration=sms_configuration, + event_destination_target=event_destination_target ) print("Rented Number:\n", response) diff --git a/examples/snippets/numbers/available_numbers/search_for_available_numbers/snippet.py b/examples/snippets/numbers/available_numbers/search_for_available_numbers/snippet.py index ac1a8301..8d174729 100644 --- a/examples/snippets/numbers/available_numbers/search_for_available_numbers/snippet.py +++ b/examples/snippets/numbers/available_numbers/search_for_available_numbers/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/numbers/available_regions/list/snippet.py b/examples/snippets/numbers/available_regions/list/snippet.py index 1012de9e..59ff6459 100644 --- a/examples/snippets/numbers/available_regions/list/snippet.py +++ b/examples/snippets/numbers/available_regions/list/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/numbers/event_destinations/get/snippet.py b/examples/snippets/numbers/event_destinations/get/snippet.py index 413fd0d0..3f33031e 100644 --- a/examples/snippets/numbers/event_destinations/get/snippet.py +++ b/examples/snippets/numbers/event_destinations/get/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/numbers/event_destinations/update/snippet.py b/examples/snippets/numbers/event_destinations/update/snippet.py index 51722f76..9e6dc8b0 100644 --- a/examples/snippets/numbers/event_destinations/update/snippet.py +++ b/examples/snippets/numbers/event_destinations/update/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os @@ -17,7 +16,9 @@ key_secret=os.environ.get("SINCH_KEY_SECRET") or "MY_KEY_SECRET" ) -hmac_secret = "NEW_HMAC_SECRET" +# The HMAC secret for signing webhook requests to your event destination +hmac_secret = "HMAC_SECRET" + response = sinch_client.numbers.event_destinations.update( hmac_secret=hmac_secret ) diff --git a/examples/snippets/sms/batches/cancel/snippet.py b/examples/snippets/sms/batches/cancel/snippet.py index 55bb5738..ebc64110 100644 --- a/examples/snippets/sms/batches/cancel/snippet.py +++ b/examples/snippets/sms/batches/cancel/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os @@ -20,6 +19,7 @@ # The ID of the batch to cancel batch_id = "BATCH_ID" + response = sinch_client.sms.batches.cancel(batch_id=batch_id) print(f"Cancelled batch:\n{response}") diff --git a/examples/snippets/sms/batches/dry_run_binary/snippet.py b/examples/snippets/sms/batches/dry_run_binary/snippet.py index 03b6eb9c..689cb02e 100644 --- a/examples/snippets/sms/batches/dry_run_binary/snippet.py +++ b/examples/snippets/sms/batches/dry_run_binary/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/sms/batches/dry_run_mms/snippet.py b/examples/snippets/sms/batches/dry_run_mms/snippet.py index 11f54c31..8df83795 100644 --- a/examples/snippets/sms/batches/dry_run_mms/snippet.py +++ b/examples/snippets/sms/batches/dry_run_mms/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/sms/batches/dry_run_sms/snippet.py b/examples/snippets/sms/batches/dry_run_sms/snippet.py index ae0a7d09..f9eb0ded 100644 --- a/examples/snippets/sms/batches/dry_run_sms/snippet.py +++ b/examples/snippets/sms/batches/dry_run_sms/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/sms/batches/get/snippet.py b/examples/snippets/sms/batches/get/snippet.py index 3c30df32..369851b8 100644 --- a/examples/snippets/sms/batches/get/snippet.py +++ b/examples/snippets/sms/batches/get/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os @@ -20,6 +19,7 @@ # The ID of the batch to retrieve batch_id = "BATCH_ID" + response = sinch_client.sms.batches.get(batch_id=batch_id) print(f"Batch details:\n{response}") diff --git a/examples/snippets/sms/batches/list/snippet.py b/examples/snippets/sms/batches/list/snippet.py index c6364025..15473da4 100644 --- a/examples/snippets/sms/batches/list/snippet.py +++ b/examples/snippets/sms/batches/list/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/sms/batches/replace_binary/snippet.py b/examples/snippets/sms/batches/replace_binary/snippet.py index 305e4f59..17f13be2 100644 --- a/examples/snippets/sms/batches/replace_binary/snippet.py +++ b/examples/snippets/sms/batches/replace_binary/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/sms/batches/replace_mms/snippet.py b/examples/snippets/sms/batches/replace_mms/snippet.py index fed4d71e..69bcb708 100644 --- a/examples/snippets/sms/batches/replace_mms/snippet.py +++ b/examples/snippets/sms/batches/replace_mms/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/sms/batches/replace_sms/snippet.py b/examples/snippets/sms/batches/replace_sms/snippet.py index 88066324..f2e8f373 100644 --- a/examples/snippets/sms/batches/replace_sms/snippet.py +++ b/examples/snippets/sms/batches/replace_sms/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/sms/batches/send_binary/snippet.py b/examples/snippets/sms/batches/send_binary/snippet.py index ad2366a1..f93dbb10 100644 --- a/examples/snippets/sms/batches/send_binary/snippet.py +++ b/examples/snippets/sms/batches/send_binary/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/sms/batches/send_delivery_feedback/snippet.py b/examples/snippets/sms/batches/send_delivery_feedback/snippet.py index f19f83ad..5da87fc0 100644 --- a/examples/snippets/sms/batches/send_delivery_feedback/snippet.py +++ b/examples/snippets/sms/batches/send_delivery_feedback/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/sms/batches/send_mms/snippet.py b/examples/snippets/sms/batches/send_mms/snippet.py index fff15360..6627b712 100644 --- a/examples/snippets/sms/batches/send_mms/snippet.py +++ b/examples/snippets/sms/batches/send_mms/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/sms/batches/send_sms/snippet.py b/examples/snippets/sms/batches/send_sms/snippet.py index 64cedd2d..1073cc31 100644 --- a/examples/snippets/sms/batches/send_sms/snippet.py +++ b/examples/snippets/sms/batches/send_sms/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/sms/batches/update_binary/snippet.py b/examples/snippets/sms/batches/update_binary/snippet.py index ac67b610..7b1360d0 100644 --- a/examples/snippets/sms/batches/update_binary/snippet.py +++ b/examples/snippets/sms/batches/update_binary/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/sms/batches/update_mms/snippet.py b/examples/snippets/sms/batches/update_mms/snippet.py index b8a7ba1a..7c37dbb6 100644 --- a/examples/snippets/sms/batches/update_mms/snippet.py +++ b/examples/snippets/sms/batches/update_mms/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/sms/batches/update_sms/snippet.py b/examples/snippets/sms/batches/update_sms/snippet.py index d65aa994..1e6fd4e6 100644 --- a/examples/snippets/sms/batches/update_sms/snippet.py +++ b/examples/snippets/sms/batches/update_sms/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/sms/delivery_reports/get/snippet.py b/examples/snippets/sms/delivery_reports/get/snippet.py index bcf068db..d1e715e1 100644 --- a/examples/snippets/sms/delivery_reports/get/snippet.py +++ b/examples/snippets/sms/delivery_reports/get/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os @@ -20,6 +19,7 @@ # The ID of the batch to get delivery report for batch_id = "BATCH_ID" + response = sinch_client.sms.delivery_reports.get(batch_id=batch_id) print(f"Delivery report for batch:\n{response}") diff --git a/examples/snippets/sms/delivery_reports/get_for_number/snippet.py b/examples/snippets/sms/delivery_reports/get_for_number/snippet.py index 8e304697..859a8768 100644 --- a/examples/snippets/sms/delivery_reports/get_for_number/snippet.py +++ b/examples/snippets/sms/delivery_reports/get_for_number/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os diff --git a/examples/snippets/sms/delivery_reports/list/snippet.py b/examples/snippets/sms/delivery_reports/list/snippet.py index 56f4af20..d92f88ef 100644 --- a/examples/snippets/sms/delivery_reports/list/snippet.py +++ b/examples/snippets/sms/delivery_reports/list/snippet.py @@ -1,8 +1,7 @@ """ Sinch Python Snippet -TODO: Update links when v2 is released. -This snippet is available at https://github.com/sinch/sinch-sdk-python/blob/v2.0/docs/snippets/ +This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets """ import os From cca4428444d4ab5512640b58930292a322956ee5 Mon Sep 17 00:00:00 2001 From: Jessica Matsuoka Date: Wed, 25 Mar 2026 18:53:12 +0100 Subject: [PATCH 9/9] update error messages --- sinch/core/clients/sinch_client_configuration.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sinch/core/clients/sinch_client_configuration.py b/sinch/core/clients/sinch_client_configuration.py index 1ca6af3a..0bba7730 100644 --- a/sinch/core/clients/sinch_client_configuration.py +++ b/sinch/core/clients/sinch_client_configuration.py @@ -256,7 +256,7 @@ def get_sms_origin_for_auth(self): "SMS region is required. " "Provide sms_region when initializing SinchClient " "Example: SinchClient(project_id='...', key_id='...', key_secret='...', sms_region='eu')" - "or set it via sinch_client.configuration.sms_region. " + " or set it via sinch_client.configuration.sms_region. " ) return origin @@ -273,7 +273,7 @@ def get_conversation_origin(self): "Conversation region is required. " "Provide conversation_region when initializing SinchClient " "Example: SinchClient(project_id='...', key_id='...', key_secret='...', conversation_region='eu')" - "or set it via sinch_client.configuration.conversation_region. " + " or set it via sinch_client.configuration.conversation_region. " ) return self.conversation_origin