Skip to content

Commit 4b55bd9

Browse files
authored
Merge branch 'v2.1-next' into feature/DEVEXP-808-sms-inbounds
2 parents aee8a9f + dc9a3fa commit 4b55bd9

59 files changed

Lines changed: 2598 additions & 227 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ jobs:
8585
cp sinch-sdk-mockserver/features/numbers/numbers.feature ./tests/e2e/numbers/features/
8686
cp sinch-sdk-mockserver/features/numbers/webhooks.feature ./tests/e2e/numbers/features/
8787
cp sinch-sdk-mockserver/features/sms/delivery-reports.feature ./tests/e2e/sms/features/
88+
cp sinch-sdk-mockserver/features/sms/groups.feature ./tests/e2e/sms/features/
89+
cp sinch-sdk-mockserver/features/sms/groups_servicePlanId.feature ./tests/e2e/sms/features/
8890
cp sinch-sdk-mockserver/features/sms/delivery-reports_servicePlanId.feature ./tests/e2e/sms/features/
8991
cp sinch-sdk-mockserver/features/sms/batches.feature ./tests/e2e/sms/features/
9092
cp sinch-sdk-mockserver/features/sms/batches_servicePlanId.feature ./tests/e2e/sms/features/

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,14 @@ All notable changes to the **Sinch Python SDK** are documented in this file.
1818

1919
## v2.1.0 – 2026-06-05
2020

21+
### SDK
22+
23+
- **[dependency]** Set up minimum version for `requests` to `>=2.0.0` to prevent pulling in versions with known vulnerabilities (#152).
24+
25+
2126
### SMS
2227

28+
- **[feature]** SMS Groups API: `create`, `list`, `get`, `update`, `replace`, `delete`, and `list_members` operations, with full model, endpoint, and unit test coverage (see [MIGRATION_GUIDE.md](MIGRATION_GUIDE.md#groups-api)).
2329
- **[feature]** SMS Inbounds API: `get` and `list` operations, with full model, endpoint, and unit test coverage (see [MIGRATION_GUIDE.md](MIGRATION_GUIDE.md#210)).
2430
- **[design]** SMS Sinch Events inbound payload models unified with the Inbounds API: `MOTextSinchEvent`, `MOBinarySinchEvent`, `MOMediaSinchEvent`, `MediaBody`, and `MediaItem` removed from `sinch_events`; use `InboundMessage` (and its variants) from `sinch.domains.sms.models.v1.types` instead (see [MIGRATION_GUIDE.md](MIGRATION_GUIDE.md#210)).
2531

MIGRATION_GUIDE.md

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Sinch Python SDK Migration Guide
22

3-
## 2.0.0
3+
## 2.1.0
44

55
This release removes legacy SDK support.
66

@@ -205,7 +205,7 @@ The Conversation HTTP API still expects the JSON field **`callback_url`**. In V2
205205

206206
#### Replacement APIs
207207

208-
The SMS domain API access remains the same: `sinch.sms.batches`, `sinch.sms.delivery_reports`, and `sinch.sms.inbounds`. However, the underlying models and method signatures have changed.
208+
The SMS domain API access remains the same: `sinch.sms.batches`, `sinch.sms.delivery_reports`, `sinch.sms.inbounds` and `sinch.sms.groups`. However, the underlying models and method signatures have changed.
209209

210210
##### Batches API
211211

@@ -228,6 +228,39 @@ The SMS domain API access remains the same: `sinch.sms.batches`, `sinch.sms.deli
228228
| `get_for_batch()` with `GetSMSDeliveryReportForBatchRequest` | `get()` with `batch_id: str` and optional parameters: `report_type`, `status`, `code`, `client_reference` |
229229
| `get_for_number()` with `GetSMSDeliveryReportForNumberRequest` | `get_for_number()` with `batch_id: str` and `recipient: str` parameters |
230230

231+
##### Groups API
232+
233+
###### Replacement models
234+
235+
| Old class | New class |
236+
|-----------|-----------|
237+
| `sinch.domains.sms.models.groups.requests.CreateSMSGroupRequest` | [`sinch.domains.sms.models.v1.internal.GroupRequest`](sinch/domains/sms/models/v1/internal/group_request.py) |
238+
| `sinch.domains.sms.models.groups.requests.ListSMSGroupRequest` | [`sinch.domains.sms.models.v1.internal.ListGroupsRequest`](sinch/domains/sms/models/v1/internal/list_groups_request.py) |
239+
| `sinch.domains.sms.models.groups.requests.GetSMSGroupRequest` | [`sinch.domains.sms.models.v1.internal.GroupIdRequest`](sinch/domains/sms/models/v1/internal/group_id_request.py) |
240+
| `sinch.domains.sms.models.groups.requests.DeleteSMSGroupRequest` | [`sinch.domains.sms.models.v1.internal.GroupIdRequest`](sinch/domains/sms/models/v1/internal/group_id_request.py) |
241+
| `sinch.domains.sms.models.groups.requests.GetSMSGroupPhoneNumbersRequest` | [`sinch.domains.sms.models.v1.internal.GroupIdRequest`](sinch/domains/sms/models/v1/internal/group_id_request.py) |
242+
| `sinch.domains.sms.models.groups.requests.UpdateSMSGroupRequest` | [`sinch.domains.sms.models.v1.internal.UpdateGroupRequest`](sinch/domains/sms/models/v1/internal/update_group_request.py) |
243+
| `sinch.domains.sms.models.groups.requests.ReplaceSMSGroupPhoneNumbersRequest` | [`sinch.domains.sms.models.v1.internal.ReplaceGroupRequest`](sinch/domains/sms/models/v1/internal/replace_group_request.py) |
244+
| `sinch.domains.sms.models.groups.responses.CreateSMSGroupResponse` | [`sinch.domains.sms.models.v1.response.GroupResponse`](sinch/domains/sms/models/v1/response/group_response.py) |
245+
| `sinch.domains.sms.models.groups.responses.GetSMSGroupResponse` | [`sinch.domains.sms.models.v1.response.GroupResponse`](sinch/domains/sms/models/v1/response/group_response.py) |
246+
| `sinch.domains.sms.models.groups.responses.UpdateSMSGroupResponse` | [`sinch.domains.sms.models.v1.response.GroupResponse`](sinch/domains/sms/models/v1/response/group_response.py) |
247+
| `sinch.domains.sms.models.groups.responses.ReplaceSMSGroupResponse` | [`sinch.domains.sms.models.v1.response.GroupResponse`](sinch/domains/sms/models/v1/response/group_response.py) |
248+
| `sinch.domains.sms.models.groups.responses.SinchListSMSGroupResponse` | [`sinch.domains.sms.models.v1.response.ListGroupsResponse`](sinch/domains/sms/models/v1/response/list_groups_response.py) |
249+
| `sinch.domains.sms.models.groups.responses.SinchGetSMSGroupPhoneNumbersResponse` | [`sinch.domains.sms.models.v1.response.ListGroupMembersResponse`](sinch/domains/sms/models/v1/response/list_group_members_response.py) |
250+
| `sinch.domains.sms.models.groups.responses.SinchDeleteSMSGroupResponse` | `None` (method returns `None`) |
251+
252+
###### Replacement APIs
253+
254+
| Old method | New method in `sms.groups` |
255+
|------------|---------------------------|
256+
| `create()` with `CreateSMSGroupRequest` | `create()` with individual parameters: `name`, `members`, `child_groups`, `auto_update` |
257+
| `list()` with `ListSMSGroupRequest` | `list()` with individual parameters: `page`, `page_size`. Returns **`Paginator[GroupResponse]`** |
258+
| `get()` with `GetSMSGroupRequest` | `get()` with `group_id: str` parameter |
259+
| `update()` with `UpdateSMSGroupRequest` | `update()` with `group_id: str` and optional parameters: `add`, `remove`, `name`, `add_from_group`, `remove_from_group`, `auto_update` |
260+
| `replace()` with `ReplaceSMSGroupPhoneNumbersRequest` | `replace()` with `group_id: str` and optional parameters: `name`, `members`, `child_groups`, `auto_update` |
261+
| `delete()` with `DeleteSMSGroupRequest` | `delete()` with `group_id: str` parameter |
262+
| `get_phone_numbers()` / phone number listing | `list_members()` with `group_id: str`. Returns **`Paginator[str]`** |
263+
231264
##### Inbounds API
232265

233266
###### Replacement models
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"""
2+
Sinch Python Snippet
3+
4+
This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets
5+
"""
6+
7+
import os
8+
9+
from dotenv import load_dotenv
10+
11+
from sinch import SinchClient
12+
13+
load_dotenv()
14+
15+
sinch_client = SinchClient(
16+
project_id=os.environ.get("SINCH_PROJECT_ID") or "MY_PROJECT_ID",
17+
key_id=os.environ.get("SINCH_KEY_ID") or "MY_KEY_ID",
18+
key_secret=os.environ.get("SINCH_KEY_SECRET") or "MY_KEY_SECRET",
19+
sms_region=os.environ.get("SINCH_SMS_REGION") or "MY_SMS_REGION"
20+
)
21+
22+
response = sinch_client.sms.groups.create(
23+
name="Sinch Python SDK group", members=["+1234567890", "+1987654321"]
24+
)
25+
26+
print(f"Group created:\n{response}")
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""
2+
Sinch Python Snippet
3+
4+
This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets
5+
"""
6+
7+
import os
8+
9+
from dotenv import load_dotenv
10+
11+
from sinch import SinchClient
12+
13+
load_dotenv()
14+
15+
sinch_client = SinchClient(
16+
project_id=os.environ.get("SINCH_PROJECT_ID") or "MY_PROJECT_ID",
17+
key_id=os.environ.get("SINCH_KEY_ID") or "MY_KEY_ID",
18+
key_secret=os.environ.get("SINCH_KEY_SECRET") or "MY_KEY_SECRET",
19+
sms_region=os.environ.get("SINCH_SMS_REGION") or "MY_SMS_REGION"
20+
)
21+
22+
# The ID of the group to delete
23+
group_id = "GROUP_ID"
24+
25+
sinch_client.sms.groups.delete(group_id=group_id)
26+
27+
print(f"Group {group_id} deleted")
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
"""
2+
Sinch Python Snippet
3+
4+
This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets
5+
"""
6+
7+
import os
8+
9+
from dotenv import load_dotenv
10+
11+
from sinch import SinchClient
12+
13+
load_dotenv()
14+
15+
sinch_client = SinchClient(
16+
project_id=os.environ.get("SINCH_PROJECT_ID") or "MY_PROJECT_ID",
17+
key_id=os.environ.get("SINCH_KEY_ID") or "MY_KEY_ID",
18+
key_secret=os.environ.get("SINCH_KEY_SECRET") or "MY_KEY_SECRET",
19+
sms_region=os.environ.get("SINCH_SMS_REGION") or "MY_SMS_REGION"
20+
)
21+
22+
# The ID of the group to retrieve
23+
GROUP_ID = "GROUP_ID"
24+
25+
response = sinch_client.sms.groups.get(
26+
group_id=GROUP_ID
27+
)
28+
29+
print(f"Group details:\n{response}")
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"""
2+
Sinch Python Snippet
3+
4+
This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets
5+
"""
6+
7+
import os
8+
9+
from dotenv import load_dotenv
10+
11+
from sinch import SinchClient
12+
13+
load_dotenv()
14+
15+
sinch_client = SinchClient(
16+
project_id=os.environ.get("SINCH_PROJECT_ID") or "MY_PROJECT_ID",
17+
key_id=os.environ.get("SINCH_KEY_ID") or "MY_KEY_ID",
18+
key_secret=os.environ.get("SINCH_KEY_SECRET") or "MY_KEY_SECRET",
19+
sms_region=os.environ.get("SINCH_SMS_REGION") or "MY_SMS_REGION"
20+
)
21+
22+
groups = sinch_client.sms.groups.list()
23+
24+
print("List of groups:\n")
25+
for group in groups.iterator():
26+
print(group)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"""
2+
Sinch Python Snippet
3+
4+
This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets
5+
"""
6+
7+
import os
8+
from typing import List
9+
10+
from dotenv import load_dotenv
11+
12+
from sinch import SinchClient
13+
14+
load_dotenv()
15+
16+
sinch_client = SinchClient(
17+
project_id=os.environ.get("SINCH_PROJECT_ID") or "MY_PROJECT_ID",
18+
key_id=os.environ.get("SINCH_KEY_ID") or "MY_KEY_ID",
19+
key_secret=os.environ.get("SINCH_KEY_SECRET") or "MY_KEY_SECRET",
20+
sms_region=os.environ.get("SINCH_SMS_REGION") or "MY_SMS_REGION"
21+
)
22+
23+
# The ID of the group to list members for
24+
group_id = "GROUP_ID"
25+
26+
members = sinch_client.sms.groups.list_members(group_id=group_id)
27+
28+
print("List of members:\n")
29+
for member in members.iterator():
30+
print(member)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"""
2+
Sinch Python Snippet
3+
4+
This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets
5+
"""
6+
7+
import os
8+
9+
from dotenv import load_dotenv
10+
11+
from sinch import SinchClient
12+
13+
load_dotenv()
14+
15+
sinch_client = SinchClient(
16+
project_id=os.environ.get("SINCH_PROJECT_ID") or "MY_PROJECT_ID",
17+
key_id=os.environ.get("SINCH_KEY_ID") or "MY_KEY_ID",
18+
key_secret=os.environ.get("SINCH_KEY_SECRET") or "MY_KEY_SECRET",
19+
sms_region=os.environ.get("SINCH_SMS_REGION") or "MY_SMS_REGION"
20+
)
21+
22+
# The ID of the group to replace
23+
group_id = "GROUP_ID"
24+
25+
response = sinch_client.sms.groups.replace(
26+
group_id=group_id,
27+
members=["+1234567890", "+1987654321"],
28+
)
29+
30+
print(f"Group replaced:\n{response}")
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""
2+
Sinch Python Snippet
3+
4+
This snippet is available at https://github.com/sinch/sinch-sdk-python/tree/main/examples/snippets
5+
"""
6+
7+
import os
8+
9+
from dotenv import load_dotenv
10+
11+
from sinch import SinchClient
12+
13+
load_dotenv()
14+
15+
sinch_client = SinchClient(
16+
project_id=os.environ.get("SINCH_PROJECT_ID") or "MY_PROJECT_ID",
17+
key_id=os.environ.get("SINCH_KEY_ID") or "MY_KEY_ID",
18+
key_secret=os.environ.get("SINCH_KEY_SECRET") or "MY_KEY_SECRET",
19+
sms_region=os.environ.get("SINCH_SMS_REGION") or "MY_SMS_REGION"
20+
)
21+
22+
# The ID of the group to update
23+
group_id = "GROUP_ID"
24+
25+
response = sinch_client.sms.groups.update(
26+
group_id=group_id,
27+
add=["+1234567890"],
28+
remove=["+1987654321"],
29+
name="Renamed Group",
30+
)
31+
32+
print(f"Group updated:\n{response}")

0 commit comments

Comments
 (0)