Skip to content

Add support for notification trigger management and poll notifications - #448

Merged
const-cloudinary merged 1 commit into
masterfrom
feature/poll-notifications
Aug 18, 2026
Merged

Add support for notification trigger management and poll notifications#448
const-cloudinary merged 1 commit into
masterfrom
feature/poll-notifications

Conversation

@const-cloudinary

Copy link
Copy Markdown
Member

Adds trigger management and the poll notification transport to the Python SDK. Poll notifications let a client receive notifications without exposing a public webhook endpoint: notifications are buffered server-side against a poll:// trigger and drained over long-poll.

Admin API

Trigger management: triggers, create_trigger, update_trigger, delete_trigger, test_trigger.

Poll transport: notifications and ack_notifications, addressed by either a named channel or a batch_id. notifications raises ValueError unless exactly one of the two is given, mirroring the server.

Signature verification

utils.verify_notification(message) verifies a polled message envelope directly:

for msg in api.notifications(channel="orders", wait_seconds=20).get("messages", []):
    if utils.verify_notification(msg):
        handle(msg["payload"])

It decodes signed_payload and verifies against those bytes, then delegates to the existing verify_notification_signature. This matters because signatures cover the byte-exact signed payload: verifying against a re-serialization of the parsed payload, or against the undecoded base64, returns a silent False that reads as a forged notification. utils.base64url_decode is exposed for callers who need the raw bytes.

Also fixes a TypeError in verify_notification_signature when timestamp is a string — the form both the poll envelope and the X-Cld-Timestamp header actually deliver, so the comparison raised on every real message.

Other changes

  • batch_id on upload, archive, multi, sprite and bulk delete parameters (signed automatically)
  • request_id on Admin API responses (Response.request_id attribute) and Upload API results (request_id key). The Upload API return type stays a plain dict
  • Module-first URLs in the v2 API client (/v2/{module}/{cloud_name}/...), which the notifications endpoints require
  • cloudinary.config(timeout=...) now honored on Admin API calls; a per-call timeout still wins
  • HTTP 503 mapped to GeneralError

Testing

Mocked coverage for triggers, notifications, verification and request_id propagation, plus two live end-to-end tests: a trigger create/list/update/delete lifecycle, and an upload that is polled, signature-verified and acknowledged against the real API. Both clean up after themselves and skip without credentials.

Verified against a live product environment: 178 passed.

Adds the trigger management Admin API (`triggers`, `create_trigger`,
`update_trigger`, `delete_trigger`, `test_trigger`) and the poll notification
transport (`notifications`, `ack_notifications`), addressed by named channel or
`batch_id`.

Adds `utils.verify_notification` to verify a polled message envelope, and
`utils.base64url_decode` to decode its `signed_payload`. Fixes a `TypeError` in
`verify_notification_signature` when the timestamp is a string, which is the form
both the poll envelope and the `X-Cld-Timestamp` header deliver.

Adds `batch_id` to upload, archive, multi, sprite and bulk delete parameters, and
`request_id` to Admin API responses (`Response.request_id`) and Upload API results.
Supports module-first URLs in the v2 API client, honors `cloudinary.config(timeout=...)`
on Admin calls, and maps HTTP 503 to `GeneralError`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@const-cloudinary
const-cloudinary merged commit 1df38cd into master Aug 18, 2026
16 checks passed
@const-cloudinary
const-cloudinary deleted the feature/poll-notifications branch August 18, 2026 13:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant