// the find
anymail/django-anymail
Django email backends and webhooks for Amazon SES, Brevo, MailerSend, Mailgun, Mailjet, Mailtrap, Postmark, Postal, Resend, Scaleway TEM, SendGrid, SparkPost, Unisender Go and more
Anymail wraps Django's built-in email system to support 14+ transactional ESPs through a single consistent API. Swap backends by changing one setting; your `send_mail()` calls stay untouched. Aimed at Django shops that want to avoid rewriting email code if they ever switch providers.
1. The abstraction actually holds up — tags, metadata, webhooks, and inbound parsing are all normalized across ESPs, not just the send path. 2. Test backend ships with the library, so you can assert on sent messages in unit tests without mocking anything yourself. 3. Webhook handling is first-class: Django signals fire for delivery events, bounces, clicks, opens — same signal interface regardless of which ESP fired it. 4. Test coverage is thorough and honest — per-ESP backend tests, webhook tests, and live integration tests with separate CI jobs.
1. SendGrid support is officially untested as of the latest release — that's a significant omission given how common it is. 2. Async Django (ASGI) is not supported; all sending is synchronous. In a high-throughput async view you'll need to push sends to a task queue or thread pool yourself. 3. ESP-specific features that don't map to the common API require dropping down to `esp_extra`, which ties your code to a specific backend anyway — partially defeats the portability story. 4. Minimal retry/backoff logic built in; transient ESP errors are surfaced as exceptions and left for you to handle upstream.