Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,96 @@ Note that `sinch.sms.groups` and `sinch.sms.inbounds` are not supported yet and
| `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)

##### Replacement APIs / attributes

| Old | New |
|-----|-----|
| `sinch_client.numbers.callbacks` (attribute) | `sinch_client.numbers.event_destinations` (attribute) |
| `numbers.callbacks.get_configuration()` (method) | `numbers.event_destinations.get()` (method) |
| `numbers.callbacks.update_configuration(hmac_secret)` (method) | `numbers.event_destinations.update(hmac_secret=hmac_secret)` (method) |

##### Replacement models

| Old class | New class |
|-----------|-----------|
| `UpdateNumbersCallbackConfigurationRequest` | `UpdateEventDestinationRequest` |
| `GetNumbersCallbackConfigurationResponse` | `EventDestinationResponse` |
| `UpdateNumbersCallbackConfigurationResponse` | `EventDestinationResponse` |

**Example:**

```python
# Old
config = sinch_client.numbers.callbacks.get_configuration()
sinch_client.numbers.callbacks.update_configuration("your_hmac_secret")

# New
config = sinch_client.numbers.event_destinations.get()
sinch_client.numbers.event_destinations.update(hmac_secret="your_hmac_secret")
```

##### Available and Active: method locations

| Old method | New method |
|------------|------------|
| `numbers.available.rent_any(...)`, `numbers.available.activate(...)`, `numbers.available.check_availability(...)`, `numbers.available.list(...)` | `numbers.rent_any(...)`, `numbers.rent(...)`, `numbers.check_availability(...)`, `numbers.search_for_available_numbers(...)` |
| `numbers.active.list(...)`, `numbers.active.get(...)`, `numbers.active.update(...)`, `numbers.active.release(...)` | `numbers.list(...)`, `numbers.get(...)`, `numbers.update(...)`, `numbers.release(...)` |

#### Sinch Events (Event Destinations payload models and package path)

| Old | New |
|-----|-----|
| — _(N/A)_ | `sinch.domains.numbers.sinch_events` (package path) |
| — | `NumberSinchEvent` (class, payload model) |

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
handler = sinch_client.numbers.sinch_events("your_callback_secret")
event = handler.parse_event(request_body) # event is a NumberSinchEvent
```

#### Request and response fields: callback URL → event destination target

| | Old | New |
|---|-----|-----|
| **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 |
|-----|-----|
| `RentAnyNumberRequest.callback_url` | `RentNumberRequest.event_destination_target`, `RentAnyNumberRequest.event_destination_target`, `UpdateNumberConfigurationRequest.event_destination_target` |
| `ActiveNumber` has no callback field | `ActiveNumber.event_destination_target` (response) |

**Example:**

```python
# Old
sinch_client.numbers.available.rent_any(
region_code="US",
type_="LOCAL",
sms_configuration={...},
voice_configuration={...},
callback_url="https://example.com/events",
)

# New
sinch_client.numbers.rent_any(
region_code="US",
number_type="LOCAL",
sms_configuration={...},
voice_configuration={...},
event_destination_target="https://example.com/events",
)
```
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Webhook Handlers for Sinch Python SDK
# Sinch Events Handlers for Sinch Python SDK

This directory contains a server application built with [Sinch Python SDK](https://github.com/sinch/sinch-sdk-python)
to process incoming webhooks from Sinch services.
Expand All @@ -21,7 +21,7 @@ This directory contains both the webhook handlers and the server application (`s
## Configuration

1. **Environment Variables**:
Rename [.env.example](.env.example) to `.env` in this directory (`examples/webhooks/`), then add your credentials from the Sinch dashboard under the Access Keys section.
Rename [.env.example](.env.example) to `.env` in this directory (`examples/sinch_events/`), then add your credentials from the Sinch dashboard under the Access Keys section.

- Server Port:
Define the port your server will listen to on (default: 3001):
Expand All @@ -30,7 +30,7 @@ This directory contains both the webhook handlers and the server application (`s
```

- Controller Settings
- Numbers controller: Set the `numbers` webhook secret. You can retrieve it using the `/callback_configuration` endpoint (see SDK implementation: [callback_configuration_apis.py](https://github.com/sinch/sinch-sdk-python/blob/v2.0/sinch/domains/numbers/api/v1/callback_configuration_apis.py); for additional details, refer to the [Numbers API callbacks documentation](https://developers.sinch.com/docs/numbers/api-reference/numbers/tag/Numbers-Callbacks/)):
- Numbers controller: Set the `numbers` Sinch Event secret. You can retrieve it using the `/event_destination` endpoint (see SDK implementation: [event_destinations_apis.py](https://github.com/sinch/sinch-sdk-python/blob/v2.0/sinch/domains/numbers/api/v1/event_destinations_apis.py); for additional details, refer to the [Numbers API callbacks documentation](https://developers.sinch.com/docs/numbers/api-reference/numbers/tag/Numbers-Callbacks/)):
```
NUMBERS_WEBHOOKS_SECRET=Your Sinch Numbers Webhook Secret
```
Expand All @@ -49,9 +49,9 @@ This directory contains both the webhook handlers and the server application (`s

### Running the server application

1. Navigate to the webhooks' directory:
1. Navigate to the examples events directory:
```
cd examples/webhooks
cd examples/sinch_events
```

2. Install the project dependencies:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,21 @@ def numbers_event(self):
headers = dict(request.headers)
raw_body = request.raw_body if request.raw_body else b""

webhooks_service = self.sinch_client.numbers.webhooks(self.webhooks_secret)
sinch_events_service = self.sinch_client.numbers.sinch_events(
self.webhooks_secret
)

ensure_valid_authentication = False
if ensure_valid_authentication:
valid_auth = webhooks_service.validate_authentication_header(
valid_auth = sinch_events_service.validate_authentication_header(
headers=headers,
json_payload=raw_body,
)

if not valid_auth:
return Response(status=401)

event = webhooks_service.parse_event(raw_body, headers)
event = sinch_events_service.parse_event(raw_body, headers)

handle_numbers_event(numbers_event=event, logger=self.logger)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from sinch.domains.numbers.webhooks.v1.events.numbers_webhooks_event import NumbersWebhooksEvent
from sinch.domains.numbers.sinch_events.v1.events import NumberSinchEvent


def handle_numbers_event(numbers_event: NumbersWebhooksEvent, logger):
def handle_numbers_event(numbers_event: NumberSinchEvent, logger):
"""
This method handles a Numbers event.
Args:
numbers_event (NumbersWebhooksEvent): The Numbers event data.
numbers_event (NumberSinchEvent): The Numbers event data.
logger (logging.Logger, optional): Logger instance for logging. Defaults to None.
"""
logger.info(f'Handling Numbers event:\n{numbers_event.model_dump_json(indent=2)}')
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@
key_secret=os.environ.get("SINCH_KEY_SECRET") or "MY_KEY_SECRET"
)

response = sinch_client.numbers.callback_configuration.get()
response = sinch_client.numbers.event_destinations.get()

print("Callback Configuration:\n", response)
print("Event Destination Configuration:\n", response)
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
)

hmac_secret = "NEW_HMAC_SECRET"
response = sinch_client.numbers.callback_configuration.update(
response = sinch_client.numbers.event_destinations.update(
hmac_secret=hmac_secret
)

print("Updated callback configuration:\n", response)
print("Updated event destination configuration:\n", response)
6 changes: 3 additions & 3 deletions sinch/domains/numbers/api/v1/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
from sinch.domains.numbers.api.v1.available_regions_apis import (
AvailableRegions,
)
from sinch.domains.numbers.api.v1.callback_configuration_apis import (
CallbackConfiguration,
from sinch.domains.numbers.api.v1.event_destinations_apis import (
EventDestinations,
)


__all__ = [
"ActiveNumbers",
"AvailableNumbers",
"AvailableRegions",
"CallbackConfiguration",
"EventDestinations",
]
4 changes: 2 additions & 2 deletions sinch/domains/numbers/api/v1/active_numbers_apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,15 @@ def update(
display_name: Optional[str] = None,
sms_configuration: Optional[SmsConfigurationDict] = None,
voice_configuration: Optional[VoiceConfigurationDict] = None,
callback_url: Optional[str] = None,
event_destination_target: Optional[str] = None,
**kwargs,
) -> ActiveNumber:
request_data = UpdateNumberConfigurationRequest(
phone_number=phone_number,
display_name=display_name,
sms_configuration=sms_configuration,
voice_configuration=voice_configuration,
callback_url=callback_url,
event_destination_target=event_destination_target,
**kwargs,
)
return self._request(UpdateNumberConfigurationEndpoint, request_data)
Expand Down
8 changes: 4 additions & 4 deletions sinch/domains/numbers/api/v1/available_numbers_apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,14 @@ def rent(
phone_number: str,
sms_configuration: Optional[SmsConfigurationDict] = None,
voice_configuration: Optional[VoiceConfigurationDict] = None,
callback_url: Optional[str] = None,
event_destination_target: Optional[str] = None,
**kwargs,
) -> ActiveNumber:
request_data = RentNumberRequest(
phone_number=phone_number,
sms_configuration=sms_configuration,
voice_configuration=voice_configuration,
callback_url=callback_url,
event_destination_target=event_destination_target,
**kwargs,
)
return self._request(RentNumberEndpoint, request_data)
Expand All @@ -86,7 +86,7 @@ def rent_any(
capabilities: Optional[List[CapabilityType]] = None,
sms_configuration: Optional[SmsConfigurationDict] = None,
voice_configuration: Optional[VoiceConfigurationDict] = None,
callback_url: Optional[str] = None,
event_destination_target: Optional[str] = None,
**kwargs,
) -> ActiveNumber:
request_data = RentAnyNumberRequest(
Expand All @@ -96,7 +96,7 @@ def rent_any(
capabilities=capabilities,
sms_configuration=sms_configuration,
voice_configuration=voice_configuration,
callback_url=callback_url,
event_destination_target=event_destination_target,
**kwargs,
)
return self._request(RentAnyNumberEndpoint, request_data)
55 changes: 0 additions & 55 deletions sinch/domains/numbers/api/v1/callback_configuration_apis.py

This file was deleted.

53 changes: 53 additions & 0 deletions sinch/domains/numbers/api/v1/event_destinations_apis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from sinch.domains.numbers.api.v1.base import BaseNumbers
from sinch.domains.numbers.api.v1.internal import (
GetEventDestinationEndpoint,
UpdateEventDestinationEndpoint,
)
from sinch.domains.numbers.models.v1.internal import (
UpdateEventDestinationRequest,
)
from sinch.domains.numbers.models.v1.internal.base import (
BaseModelConfigurationRequest,
)
from sinch.domains.numbers.models.v1.response import (
EventDestinationResponse,
)


class EventDestinations(BaseNumbers):
def get(self, **kwargs) -> EventDestinationResponse:
"""
Returns the event destination configuration for the specified project

:param kwargs: Additional parameters for the request.
:type kwargs: dict

:returns: The event destination configuration for the project.
:rtype: EventDestinationResponse

For detailed documentation, visit: https://developers.sinch.com
"""
request_data = None
if kwargs:
request_data = BaseModelConfigurationRequest(**kwargs)
return self._request(GetEventDestinationEndpoint, request_data)

def update(self, hmac_secret: str, **kwargs) -> EventDestinationResponse:
"""
Updates the event destination configuration for the specified project

:param hmac_secret: The HMAC secret used to sign the event destination requests.
:type hmac_secret: str

:param kwargs: Additional parameters for the request.
:type kwargs: dict

:returns: The updated event destination configuration for the project.
:rtype: EventDestinationResponse

For detailed documentation, visit https://developers.sinch.com
"""
request_data = UpdateEventDestinationRequest(
hmac_secret=hmac_secret, **kwargs
)
return self._request(UpdateEventDestinationEndpoint, request_data)
Loading
Loading