anymail / django-anymail

Django email backends and webhooks for Amazon SES, Brevo (Sendinblue), MailerSend, Mailgun, Mailjet, Postmark, Postal, Resend, SendGrid, SparkPost, Unisender Go and more
https://anymail.dev
BSD 3-Clause "New" or "Revised" License
1.65k stars 125 forks source link
amazon-ses brevo django email mailersend mailgun mailjet mandrill postal postmark resend resend-email sendgrid sendinblue sparkpost unisender unisender-go

Anymail: Django email integration for transactional ESPs

.. This README is reused in multiple places:

.. 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:

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

Anymail 1-2-3

.. _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":

  1. 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.)

  2. 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 = "you@example.com"  # if you don't already have this in settings
    SERVER_EMAIL = "your-server@example.com"  # ditto (default from-email for Django errors)
  3. 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 <from@example.com>", ["to@example.com"])

    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 <admin@example.com>",
        to=["New User <user1@example.com>", "account.manager@example.com"],
        reply_to=["Helpdesk <support@example.com>"])
    
    # Include an inline image in the html:
    logo_cid = attach_inline_image_file(msg, "/path/to/logo.jpg")
    html = """<img alt="Logo" src="https://github.com/anymail/django-anymail/raw/main/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.