Skip to content
17 changes: 4 additions & 13 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand All @@ -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
Expand Down Expand Up @@ -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: |
Expand All @@ -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


21 changes: 13 additions & 8 deletions MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -62,6 +64,8 @@ token_client = SinchClient(
sinch_client.configuration.sms_region = "eu"
```

---

### Conversation Region

**In V1:**
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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()`<br>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

Expand Down Expand Up @@ -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).

<br>
---

### [`SMS`](https://github.com/sinch/sinch-sdk-python/tree/main/sinch/domains/sms)

Expand Down Expand Up @@ -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
Expand All @@ -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()`<br>Or `update()` with `UpdateBatchMessageRequest` (Union of `UpdateTextRequestWithBatchId`, `UpdateBinaryRequestWithBatchId`, `UpdateMediaRequestWithBatchId`) |
| `replace()` with `ReplaceBatchRequest` | Use convenience methods: `replace_sms()`, `replace_binary()`, `replace_mms()`<br>Or `replace()` with `ReplaceBatchRequest` (Union of `ReplaceTextRequest`, `ReplaceBinaryRequest`, `ReplaceMediaRequest`) |

<br>
---

##### 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 |

<br>
---

### [`Numbers` (Virtual Numbers)](https://github.com/sinch/sinch-sdk-python/tree/main/sinch/domains/numbers)

Expand Down Expand Up @@ -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
Expand All @@ -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 |
Expand Down
38 changes: 17 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -79,41 +79,37 @@ 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:
1. If no configuration was provided via `logger_name` or `logger` configurable, SDK will inherit configuration from the root logger with the `Sinch` prefix.
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

Expand All @@ -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
Expand Down Expand Up @@ -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.
3 changes: 1 addition & 2 deletions examples/sinch_events/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
2 changes: 1 addition & 1 deletion examples/snippets/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
3 changes: 1 addition & 2 deletions examples/snippets/conversation/messages/delete/snippet.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
3 changes: 1 addition & 2 deletions examples/snippets/conversation/messages/get/snippet.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
3 changes: 1 addition & 2 deletions examples/snippets/conversation/messages/list/snippet.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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(
Expand Down
18 changes: 10 additions & 8 deletions examples/snippets/conversation/messages/send/snippet.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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}")
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Loading
Loading