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
24 changes: 6 additions & 18 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,6 @@
name: Test Python SDK
on: [ push ]

env:
AUTH_ORIGIN: ${{ secrets.AUTH_ORIGIN }}
CONVERSATION_ORIGIN: ${{ secrets.CONVERSATION_ORIGIN }}
DISABLE_SSL: ${{ secrets.DISABLE_SSL }}
KEY_ID: ${{ secrets.KEY_ID }}
KEY_SECRET: ${{ secrets.KEY_SECRET }}
NUMBERS_ORIGIN: ${{ secrets.NUMBERS_ORIGIN }}
PROJECT_ID: ${{ secrets.PROJECT_ID }}
SERVICE_PLAN_ID: ${{ secrets.SERVICE_PLAN_ID }}
SMS_ORIGIN: ${{ secrets.SMS_ORIGIN }}
TEMPLATES_ORIGIN: ${{ secrets.TEMPLATES_ORIGIN }}

jobs:
build:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -45,6 +33,10 @@ jobs:
run: |
pip install python-dotenv
python scripts/check_snippet_coverage.py

- name: Generate Documentation
run: |
make docs

- name: Lint and format check with Ruff
run: |
Expand All @@ -69,7 +61,7 @@ jobs:
uses: actions/checkout@v4
with:
repository: sinch/sinch-sdk-mockserver
token: ${{ secrets.PAT_CI }}
token: ${{ secrets.MOCKSERVER_REPO_PAT_CI }}
fetch-depth: 0
path: sinch-sdk-mockserver

Expand All @@ -84,11 +76,7 @@ jobs:
cp sinch-sdk-mockserver/features/numbers/callback-configuration.feature ./tests/e2e/numbers/features/
cp sinch-sdk-mockserver/features/numbers/numbers.feature ./tests/e2e/numbers/features/
cp sinch-sdk-mockserver/features/numbers/webhooks.feature ./tests/e2e/numbers/features/
cp sinch-sdk-mockserver/features/sms/delivery-reports.feature ./tests/e2e/sms/features/
cp sinch-sdk-mockserver/features/sms/delivery-reports_servicePlanId.feature ./tests/e2e/sms/features/
cp sinch-sdk-mockserver/features/sms/batches.feature ./tests/e2e/sms/features/
cp sinch-sdk-mockserver/features/sms/batches_servicePlanId.feature ./tests/e2e/sms/features/
cp sinch-sdk-mockserver/features/sms/webhooks.feature ./tests/e2e/sms/features/
cp sinch-sdk-mockserver/features/sms/* ./tests/e2e/sms/features/
cp sinch-sdk-mockserver/features/number-lookup/lookups.feature ./tests/e2e/number-lookup/features/
cp sinch-sdk-mockserver/features/conversation/messages.feature ./tests/e2e/conversation/features/
cp sinch-sdk-mockserver/features/conversation/webhooks-events.feature ./tests/e2e/conversation/features/
Expand Down
82 changes: 82 additions & 0 deletions .github/workflows/documentation-upload.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: Generate and upload documentation

on:
release:
types: [published]
workflow_dispatch:
inputs:
version:
description: 'Version to use for the documentation package in semver format (e.g. 1.2.3)'
required: true

jobs:
upload-documentation:
runs-on: ubuntu-latest
env:
SDK_NAME: sinch-sdk-python

steps:
- name: Checkout Code
uses: actions/checkout@v4

- name: Resolve Version
id: version
run: |
if [ "${{ github.event_name }}" = "release" ]; then
VERSION="${{ github.event.release.tag_name }}"
else
VERSION="${{ inputs.version }}"
fi
# Strip leading 'v' if present (e.g. v1.2.3 → 1.2.3)
VERSION="${VERSION#v}"
echo "value=${VERSION}" >> "$GITHUB_OUTPUT"

- name: Validate Version Format
run: |
VERSION="${{ steps.version.outputs.value }}"
SEMVER_REGEX='^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-((alpha|beta|preview)(\.[0-9]+)?))?$'
if [[ ! "$VERSION" =~ $SEMVER_REGEX ]]; then
echo "::error::Invalid version format: '$VERSION'. Expected semver (e.g. 1.2.3, 1.2.3-alpha, 1.2.3-beta.1, 1.2.3-preview)"
exit 1
fi
echo "Version '$VERSION' is valid"

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install dev dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements-dev.txt

- name: Generate Documentation
run: |
make docs

- name: Package Documentation
run: |
cd docs/build/html
zip -r "../../../${{ env.SDK_NAME }}-${{ steps.version.outputs.value }}.zip" .

- name: Upload to GitLab Registry
run: |
echo "Uploading documentation package to GitLab Registry..."
VERSION="${{ steps.version.outputs.value }}"
curl --fail --show-error --location --header "PRIVATE-TOKEN: ${{ secrets.GITLAB_REGISTRY_UPLOAD_DOC_TOKEN }}" \
--upload-file "./${{ env.SDK_NAME }}-${VERSION}.zip" \
"https://gitlab.com/api/v4/projects/63164411/packages/generic/${{ env.SDK_NAME }}/${VERSION}/${{ env.SDK_NAME }}-${VERSION}.zip"
echo "Documentation package for version ${VERSION} uploaded to GitLab Registry"

- name: Trigger Downstream GitLab Pipeline
run: |
echo "Triggering downstream GitLab pipeline to notify about new documentation package version..."
VERSION="${{ steps.version.outputs.value }}"
curl --fail --show-error --location --request POST \
--form "token=${{ secrets.GITLAB_NOTIFY_REGISTRY_UPLOADED_DOC_TOKEN }}" \
--form "ref=main" \
--form "variables[UPSTREAM_PACKAGE_NAME]=${{ env.SDK_NAME }}" \
--form "variables[UPSTREAM_PACKAGE_VERSION]=${VERSION}" \
"https://gitlab.com/api/v4/projects/63164411/trigger/pipeline"
echo "Documentation repo notified about new package version ${VERSION}"
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ coverage.xml
.hypothesis/
.pytest_cache/
cover/
lcov.info

# E2E features
*.feature
Expand All @@ -73,7 +74,9 @@ instance/
.scrapy

# Sphinx documentation
docs/_build/
docs/build/
docs/api/


# PyBuilder
.pybuilder/
Expand Down
98 changes: 63 additions & 35 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,39 @@ All notable changes to the **Sinch Python SDK** are documented in this file.

---

## v2.1.0 – 2026-06-30

### SDK

- **[feature]** OAuth token requests are now automatically retried (up to 3 times, with exponential backoff and jitter) when the authentication service is rate-limited (`HTTP 429`).
- **[dependency]** Set up minimum version for `requests` to `>=2.0.0` to prevent pulling in versions with known vulnerabilities.
- **[fix]** Fixed a race condition in OAuth token creation and renewal under concurrent requests: `TokenManagerBase` now uses a lock with double-checked locking so the initial token is fetched exactly once, and a new `refresh_auth_token(used_token)` deduplicates concurrent renewals by only fetching when the stale token still matches the cached one.
- **[refactor]** `HTTPTransport` now prepares and authenticates requests in `request()`, so the new `send_request(request_data)` receives an already-prepared `HttpRequest` and acts as a pure I/O primitive, simplifying subclassing.
- **[deprecation notice]** `HTTPTransport.send(endpoint)` is deprecated in favour of `send_request(request_data)`; the legacy method still works for backward compatibility, but will be removed in 3.0.
- **[deprecation notice]** `TokenManagerBase.invalidate_expired_token()` and `handle_invalid_token()` (and the `TokenState.EXPIRED` value) are deprecated and will be removed in 3.0, as token renewal now goes through `refresh_auth_token()`.
- **[tech]** Removed unused GitHub environment secrets from CI workflow and simplified test fixtures to use hardcoded test values.
- **[refactor]** Consolidated the duplicated per-domain `BaseModelConfiguration` classes into three shared base classes in `sinch.core.models.internal` (`BaseConfigModel`, `SnakeCaseExtrasModel`, `CamelCaseDumpModel`).
- **[doc]** Improve README structure and content.


### SMS

- **[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)).
- **[feature]** SMS Inbounds API: `get` and `list` operations, with full model, endpoint, and unit test coverage (see [MIGRATION_GUIDE.md](MIGRATION_GUIDE.md#inbounds-api)).
- **[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#sms-sinch-events)).


### Numbers

- **[feature]** `NumberSinchEvent` synchronized with the Numbers OAS spec: new `internal_failure_code` field, additional `status` values (`IN_REVIEW`, `BLOCKED`, `COMPLETED`, `REJECTED`, `EXPIRED`), a new `NUMBER_ORDER_PROCESSING` event type, and corrected event type `DEPROVISIONING_FROM_VOICE_PLATFORM` (previously `DEPROVISIONING_TO_VOICE_PLATFORM`).

---

## v2.0.1 – 2026-06-02

### SMS

- **[fix]** SMS paginator fix (#145).
- **[fix]** SMS paginator fix.

---

Expand All @@ -32,69 +60,69 @@ All notable changes to the **Sinch Python SDK** are documented in this file.

### SDK

- **[design]** Requires explicit `sms_region` and `conversation_region` on `SinchClient` before using SMS and Conversation APIs (no silent US/EU defaults); runtime failure if unset (#49, #110).
- **[design]** The v1 asynchronous client and httpx-based async stack were removed; only synchronous `SinchClient` is supported (#55).
- **[feature]** Automatic pagination via a shared `Paginator` pattern for paged list APIs (#46, #54).
- **[doc]** README and configuration tests clarify which credentials apply to each API (#48).
- **[design]** Requires explicit `sms_region` and `conversation_region` on `SinchClient` before using SMS and Conversation APIs (no silent US/EU defaults); runtime failure if unset.
- **[design]** The v1 asynchronous client and httpx-based async stack were removed; only synchronous `SinchClient` is supported.
- **[feature]** Automatic pagination via a shared `Paginator` pattern for paged list APIs.
- **[doc]** README and configuration tests clarify which credentials apply to each API.

### Conversation

- **[feature]** Messages API refresh: convenience send 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()`), `list()` as a paginator, `update()`, `event_destination_target` (wires `callback_url`), and a `sinch_client.conversation.sinch_events(...)` helper for inbound event handling (#109–#120).
- **[feature]** Conversation Sinch Events (webhooks) support (#122, #131, #132, #133).
- **[design]** Conversation webhook REST client removed; handle inbound traffic via Sinch Events (see [MIGRATION_GUIDE.md](MIGRATION_GUIDE.md)) (#131, #132, #133).
- **[feature]** Messages API refresh: convenience send 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()`), `list()` as a paginator, `update()`, `event_destination_target` (wires `callback_url`), and a `sinch_client.conversation.sinch_events(...)` helper for inbound event handling.
- **[feature]** Conversation Sinch Events (webhooks) support.
- **[design]** Conversation webhook REST client removed; handle inbound traffic via Sinch Events (see [MIGRATION_GUIDE.md](MIGRATION_GUIDE.md)).

### Numbers

- **[feature]** Flatter API (`rent`, `list`, `event_destinations`, and related entry points), `event_destination_target`, and a Numbers Sinch Events helper (#44, #53, #57, #58, #59, #62).
- **[feature]** Available Regions endpoint (#56).
- **[feature]** Webhook helper validates the signing secret in `validate_signature_header()` (#61).
- **[tech]** Numbers Events payloads are passed through without client-side pre-processing (#63).
- **[feature]** Flatter API (`rent`, `list`, `event_destinations`, and related entry points), `event_destination_target`, and a Numbers Sinch Events helper.
- **[feature]** Available Regions endpoint.
- **[feature]** Webhook helper validates the signing secret in `validate_signature_header()`.
- **[tech]** Numbers Events payloads are passed through without client-side pre-processing.

### Number Lookup

- **[feature]** Number Lookup v1 (lookup API, models, snippets, and E2E coverage) (#99, #101, #104).
- **[feature]** Number Lookup v1 (lookup API, models, snippets, and E2E coverage).

### SMS

- **[design]** SMS client configuration and authentication paths refactored for project vs service-plan credentials, including delivery-report flows (#90).
- **[feature]** SMS delivery reports models and pagination (#87). `groups` and `inbounds` are planned for a future release (see migration guide).
- **[feature]** SMS Sinch Events (webhooks) support (#103).
- **[doc]** SMS migration guide and Sinch events quickstart material (#107, #108).
- **[design]** SMS client configuration and authentication paths refactored for project vs service-plan credentials, including delivery-report flows.
- **[feature]** SMS delivery reports models and pagination. `groups` and `inbounds` are planned for a future release (see migration guide).
- **[feature]** SMS Sinch Events (webhooks) support.
- **[doc]** SMS migration guide and Sinch events quickstart material.

### Verification

- **[design]** Verification V1 APIs are removed (#124). V2 Verification support is planned in a future release (see [MIGRATION_GUIDE.md](MIGRATION_GUIDE.md)).
- **[design]** Verification V1 APIs are removed. V2 Verification support is planned in a future release (see [MIGRATION_GUIDE.md](MIGRATION_GUIDE.md)).

### Voice

- **[design]** Voice V1 APIs are removed (#124). V2 Voice support is planned in a future release (see [MIGRATION_GUIDE.md](MIGRATION_GUIDE.md)).
- **[design]** Voice V1 APIs are removed. V2 Voice support is planned in a future release (see [MIGRATION_GUIDE.md](MIGRATION_GUIDE.md)).

### Others

- **[dependency]** Pydantic v2 (`pydantic = ">=2.0.0"`).
- **[releasing]** Ruff linter adoption (#84) and CI workflow updates (#121).
- **[doc]** Snippets and Getting Started live under `examples/` (#95, #98, #105, #106, #115, #118, #125, #127).
- **[doc]** Docstring updates across Numbers, SMS, and Conversation (#64, #65, #67, #96, #97).
- **[refactor]** Model, type, and class renames (#60, #70, #82).
- **[tech]** Conversation, Numbers, and SMS models and endpoints resynchronized with OpenAPI specification (#68, #75, #123, #128, #129, #134, #135).
- **[test]** E2E test infrastructure and refactoring (#45, #66, #102); SMS batches test coverage (#91, #93, #94).
- **[releasing]** Ruff linter adoption and CI workflow updates.
- **[doc]** Snippets and Getting Started live under `examples/`.
- **[doc]** Docstring updates across Numbers, SMS, and Conversation.
- **[refactor]** Model, type, and class renames.
- **[tech]** Conversation, Numbers, and SMS models and endpoints resynchronized with OpenAPI specification.
- **[test]** E2E test infrastructure and refactoring; SMS batches test coverage.

---

## v1.1.4 – 2025-10-23

### SDK

- **[feature]** Python 3.13 and 3.14 support (#86, #89).
- **[releasing]** CI updates (#86, #89).
- **[feature]** Python 3.13 and 3.14 support.
- **[releasing]** CI updates.

---

## v1.1.3 – 2025-09-11

### Voice

- **[fix]** DTMF conference fix (#79).
- **[fix]** DTMF conference fix.

---

Expand All @@ -103,11 +131,11 @@ All notable changes to the **Sinch Python SDK** are documented in this file.
### Test

- **[test]** End-to-end tests disabled.
- **[test]** Tests and CI improvements (#41, #42, #43, #74).
- **[test]** Tests and CI improvements.

### SDK

- **[fix]** Async authentication fixes (#41, #42, #43, #74).
- **[fix]** Async authentication fixes.

### Chore

Expand All @@ -120,15 +148,15 @@ All notable changes to the **Sinch Python SDK** are documented in this file.

### SDK

- **[fix]** Remove aiohttp leftovers (#40).
- **[fix]** Remove aiohttp leftovers.

---

## v1.1.0 – 2024-12-19

### Chore

- **[releasing]** CI strategy updates (#34, #36, #29, #17).
- **[releasing]** CI strategy updates.

### Verification

Expand All @@ -148,9 +176,9 @@ All notable changes to the **Sinch Python SDK** are documented in this file.

### SDK

- **[feature]** Verification API (#26, #27, #28).
- **[feature]** Voice API (#26, #27, #28).
- **[feature]** Verification API.
- **[feature]** Voice API.

### Chore

- **[doc]** General availability README updates (#26, #27, #28).
- **[doc]** General availability README updates.
Loading
Loading