Skip to content

Commit

Permalink
Merge pull request #49 from sinch/DEVEXP_758-SinchClient_Config
Browse files Browse the repository at this point in the history
DEVEXP-758: SinchClient Configuration
  • Loading branch information
matsk-sinch authored Mar 7, 2025
2 parents 8cc9299 + b02b46a commit a9519c5
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 68 deletions.
53 changes: 35 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,47 +33,64 @@ For more information on the Sinch APIs on which this SDK is based, refer to the
You can install this package by typing:
`pip install sinch`

## Products

The Sinch client provides access to the following Sinch products:
- Numbers API
- SMS API
- Verification API
- Voice API
- Conversation API (beta release)


## Getting started


### Client initialization


To initialize communication with Sinch backed, credentials obtained from Sinch portal have to be provided to the main client class of this SDK.
It's highly advised to not hardcode those credentials, but to fetch them from environment variables:
To establish a connection with the Sinch backend, you must provide the appropriate credentials based on the API
you intend to use. For security best practices, avoid hardcoding credentials.
Instead, retrieve them from environment variables.

#### Verification and Voice APIs

To initialize the client for the **Verification** and **Voice** APIs, use the following credentials:

```python
from sinch import SinchClient

sinch_client = SinchClient(
key_id="key_id",
key_secret="key_secret",
project_id="some_project",
application_key="application_key",
application_secret="application_secret"
)
```

#### SMS API
For the SMS API in **Australia (AU)**, **Brazil (BR)**, **Canada (CA)**, **the United States (US)**,
and **the European Union (EU)**, provide the following parameters:

```python
import os
from sinch import SinchClient

sinch_client = SinchClient(
key_id=os.getenv("KEY_ID"),
key_secret=os.getenv("KEY_SECRET"),
project_id=os.getenv("PROJECT_ID"),
application_key=os.getenv("APPLICATION_KEY"),
application_secret=os.getenv("APPLICATION_SECRET")
service_plan_id="service_plan_id",
sms_api_token="api_token"
)
```

## Products
#### All Other Sinch APIs
For all other Sinch APIs, including SMS in US and EU regions, use the following parameters:

Sinch client provides access to the following Sinch products:
- Numbers
- SMS
- Verification
- Voice API
- Conversation API (beta release)
```python
from sinch import SinchClient

sinch_client = SinchClient(
project_id="project_id",
key_id="key_id",
key_secret="key_secret"
)
```

## Logging

Expand Down
60 changes: 23 additions & 37 deletions tests/unit/test_client.py
Original file line number Diff line number Diff line change
@@ -1,44 +1,30 @@
import pytest
from sinch import SinchClient, SinchClientAsync
from sinch.core.clients.sinch_client_configuration import Configuration


def test_sinch_client_initialization():
sinch_client_sync = SinchClient(
key_id="test",
key_secret="test_secret",
project_id="test_project_id"
)
assert sinch_client_sync


def test_sinch_client_async_initialization():
sinch_client_async = SinchClientAsync(
@pytest.mark.parametrize("client", [SinchClient, SinchClientAsync])
def test_sinch_client_initialization(client):
""" Test that SinchClient and SinchClientAsync can be initialized with or without parameters """
sinch_client = client(
key_id="test",
key_secret="test_secret",
project_id="test_project_id"
)
assert sinch_client_async


def test_sinch_client_has_all_business_domains(sinch_client_sync):
assert hasattr(sinch_client_sync, "authentication")
assert hasattr(sinch_client_sync, "sms")
assert hasattr(sinch_client_sync, "conversation")
assert hasattr(sinch_client_sync, "numbers")


def test_sinch_client_async_has_all_business_domains(sinch_client_async):
assert hasattr(sinch_client_async, "authentication")
assert hasattr(sinch_client_async, "sms")
assert hasattr(sinch_client_async, "conversation")
assert hasattr(sinch_client_async, "numbers")


def test_sinch_client_has_configuration_object(sinch_client_sync):
assert hasattr(sinch_client_sync, "configuration")
assert isinstance(sinch_client_sync.configuration, Configuration)


def test_sinch_client_async_has_configuration_object(sinch_client_async):
assert hasattr(sinch_client_async, "configuration")
assert isinstance(sinch_client_async.configuration, Configuration)
assert sinch_client

sinch_client_empty = client()
assert sinch_client_empty


@pytest.mark.parametrize("client", ["sinch_client_sync", "sinch_client_async"])
def test_sinch_client_expects_all_attributes(request, client):
""" Test that SinchClient and SinchClientAsync have all attributes"""
client_instance = request.getfixturevalue(client)
assert hasattr(client_instance, "authentication")
assert hasattr(client_instance, "sms")
assert hasattr(client_instance, "conversation")
assert hasattr(client_instance, "numbers")
assert hasattr(client_instance, "verification")
assert hasattr(client_instance, "voice")
assert hasattr(client_instance, "configuration")
assert isinstance(client_instance.configuration, Configuration)
53 changes: 40 additions & 13 deletions tests/unit/test_configuration.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,48 @@
import pytest
from logging import Logger, getLogger
from sinch.core.clients.sinch_client_configuration import Configuration
from sinch.core.adapters.requests_http_transport import HTTPTransportRequests
from sinch.core.token_manager import TokenManager
from sinch.core.adapters.httpx_adapter import HTTPXTransport
from sinch.core.token_manager import TokenManager, TokenManagerAsync


@pytest.mark.parametrize(
"transport_class, token_manager_class, client_fixture",
[
(HTTPTransportRequests, TokenManager, "sinch_client_sync"),
(HTTPXTransport, TokenManagerAsync, "sinch_client_async")
]
)
def test_configuration_happy_capy_expects_initialization(
request, transport_class, token_manager_class, client_fixture
):
""" Test that Configuration can be initialized with all parameters """
sinch_client = request.getfixturevalue(client_fixture)


def test_configuration_initialization_happy_path(sinch_client_sync):
client_configuration = Configuration(
key_id="Rodney",
key_secret="Mullen",
project_id="Is the King!",
transport=HTTPTransportRequests(sinch_client_sync),
token_manager=TokenManager(sinch_client_sync)
key_id="CapyKey",
key_secret="CapybaraWhisper",
project_id="CapybaraProjectX",
logger=getLogger("CapyTrace"),
connection_timeout=10,
application_key="AppybaraKey",
application_secret="SecretHabitatEntry",
service_plan_id="CappyPremiumPlan",
sms_api_token="HappyCappyToken",
transport=transport_class(sinch_client),
token_manager=token_manager_class(sinch_client)
)
assert client_configuration.key_id == "Rodney"
assert client_configuration.key_secret == "Mullen"
assert client_configuration.project_id == "Is the King!"
assert isinstance(client_configuration.transport, HTTPTransportRequests)
assert isinstance(client_configuration.token_manager, TokenManager)

assert client_configuration.key_id == "CapyKey"
assert client_configuration.key_secret == "CapybaraWhisper"
assert client_configuration.project_id == "CapybaraProjectX"
assert isinstance(client_configuration.logger, Logger)
assert client_configuration.application_key == "AppybaraKey"
assert client_configuration.application_secret == "SecretHabitatEntry"
assert client_configuration.service_plan_id == "CappyPremiumPlan"
assert client_configuration.sms_api_token == "HappyCappyToken"
assert isinstance(client_configuration.transport, transport_class)
assert isinstance(client_configuration.token_manager, token_manager_class)


def test_set_sms_region_property_and_check_that_sms_origin_was_updated(sinch_client_sync):
Expand Down

0 comments on commit a9519c5

Please sign in to comment.