PulsePigeon's published Python SDK includes PulsePigeonClient and AsyncPulsePigeonClient interfaces. Install version 1.0.0 from PyPI for the project-key surface.
For Django views, the sync client fits naturally: the view returns a response only after the email send has been accepted or rejected. Use the sync client when the email is critical to the user-facing flow (email verification, password reset).
The verified AsyncPulsePigeonClient.send_message can serve an asynchronous application boundary. For a conventional Celery worker, the synchronous interface is usually simpler. In either case, the worker configuration, not the SDK, owns retries and backoff.
Idempotency keys in Python should derive from the event that triggered the send. For a Django password reset, the reset request id is the key; for an order confirmation, the order id. The SDK accepts the key via the idempotency_key= kwarg.
Catch the documented classes instead of invented permanent/transient names. For example, correct PulsePigeonValidationError and PulsePigeonConflictError, honor PulsePigeonRateLimitError.retry_after_seconds, and apply bounded backoff to PulsePigeonServerError. Keep the HTTP API error reference and SDK method reference beside that error-handling code.