Django email backends and webhooks for Amazon SES, Brevo (Sendinblue), MailerSend, Mailgun, Mailjet, Postmark, Postal, Resend, SendGrid, SparkPost, Unisender Go and more
… This README is reused in multiple places:
* Github: project page, exactly as it appears here
* Docs: shared-intro section gets included in docs/index.rst
quickstart section gets included in docs/quickstart.rst
* PyPI: project page (via pyproject.toml readme; see also
hatch_build.py which edits in the release version number)
You can use docutils 1.0 markup, but not any Sphinx additions.
GitHub rst supports code-block, but no other block directives.
… default-role:: literal
… _shared-intro:
… This shared-intro section is also included in docs/index.rst
Anymail lets you send and receive email in Django using your choice
of transactional email service providers (ESPs). It extends the
standard django.core.mail
with many common ESP-added features, providing
a consistent API that avoids locking your code to one specific ESP
(and making it easier to change ESPs later if needed).
Anymail currently supports these ESPs:
Anymail includes:
Django's built-in email <https://docs.djangoproject.com/en/stable/topics/email/>
_Anymail maintains compatibility with all Django versions that are in mainstream
or extended support, plus (usually) a few older Django versions, and is extensively
tested on all Python versions supported by Django. (Even-older Django versions
may still be covered by an Anymail extended support release; consult the
changelog <https://anymail.dev/en/stable/changelog/>
_ for details.)
Anymail releases follow semantic versioning <https://semver.org/>
_.
The package is released under the BSD license.
… END shared-intro
… image:: https://github.com/anymail/django-anymail/workflows/test/badge.svg?branch=main
:target: https://github.com/anymail/django-anymail/actions?query=workflow:test+branch:main
:alt: test status in GitHub Actions
… image:: https://github.com/anymail/django-anymail/workflows/integration-test/badge.svg?branch=main
:target: https://github.com/anymail/django-anymail/actions?query=workflow:integration-test+branch:main
:alt: integration test status in GitHub Actions
… image:: https://readthedocs.org/projects/anymail/badge/?version=stable
:target: https://anymail.dev/en/stable/
:alt: documentation build status on ReadTheDocs
Resources
… _quickstart:
… This quickstart section is also included in docs/quickstart.rst
Here’s how to send a message.
This example uses Mailgun, but you can substitute Mailjet or Postmark or SendGrid
or SparkPost or any other supported ESP where you see “mailgun”:
Install Anymail from PyPI:
… code-block:: console
$ pip install "django-anymail[mailgun]"
(The [mailgun]
part installs any additional packages needed for that ESP.
Mailgun doesn’t have any, but some other ESPs do.)
Edit your project’s settings.py
:
… code-block:: python
INSTALLED_APPS = [
# ...
"anymail",
# ...
]
ANYMAIL = {
# (exact settings here depend on your ESP...)
"MAILGUN_API_KEY": "<your Mailgun key>",
"MAILGUN_SENDER_DOMAIN": 'mg.example.com', # your Mailgun domain, if needed
}
EMAIL_BACKEND = "anymail.backends.mailgun.EmailBackend" # or sendgrid.EmailBackend, or...
DEFAULT_FROM_EMAIL = "[email protected]" # if you don't already have this in settings
SERVER_EMAIL = "[email protected]" # ditto (default from-email for Django errors)
Now the regular Django email functions <https://docs.djangoproject.com/en/stable/topics/email/>
_
will send through your chosen ESP:
… code-block:: python
from django.core.mail import send_mail
send_mail("It works!", "This will get sent through Mailgun",
"Anymail Sender <[email protected]>", ["[email protected]"])
You could send an HTML message, complete with an inline image,
custom tags and metadata:
… code-block:: python
from django.core.mail import EmailMultiAlternatives
from anymail.message import attach_inline_image_file
msg = EmailMultiAlternatives(
subject="Please activate your account",
body="Click to activate your account: https://example.com/activate",
from_email="Example <[email protected]>",
to=["New User <[email protected]>", "[email protected]"],
reply_to=["Helpdesk <[email protected]>"])
# Include an inline image in the html:
logo_cid = attach_inline_image_file(msg, "/path/to/logo.jpg")
html = """<img alt="Logo" src="cid:{logo_cid}">
<p>Please <a href="https://example.com/activate">activate</a>
your account</p>""".format(logo_cid=logo_cid)
msg.attach_alternative(html, "text/html")
# Optional Anymail extensions:
msg.metadata = {"user_id": "8675309", "experiment_variation": 1}
msg.tags = ["activation", "onboarding"]
msg.track_clicks = True
# Send it:
msg.send()
… END quickstart
See the full documentation <https://anymail.dev/en/stable/>
_
for more features and options, including receiving messages and tracking
sent message status.