Start here

Getting started

MailingKit gives your Python application one small API for sending email. You install it, configure a provider, create one client and send. Everything else is opt-in.

Install

bash
pip install mailingkit             # console, file, memory and SMTP providers
pip install "mailingkit[resend]"   # adds the Resend provider (httpx)

MailingKit needs Python 3.11 or newer and runs on Linux, macOS and Windows. The core package depends only on Jinja2, so installing it never pulls in a web framework, a queue or a tracing library.

Send your first email

Create one client and send. With nothing configured, MailingKit uses the console provider, so this prints the email instead of sending it:

first_email.py
import asyncio
from mailingkit import MailingKit

async def main():
    mail = MailingKit.from_env(default_sender="no-reply@example.com")
    result = await mail.send(
        to="ada@example.com",
        subject="Your export is ready",
        html="<p>Hi Ada, your export is ready to <a href='https://example.com/x'>download</a>.</p>",
    )
    print(result.id, result.provider)

asyncio.run(main())

A plain text part is generated from the HTML automatically, because a text alternative improves deliverability. Pass text= yourself if you want to control it.

Configure a real provider

When you are ready to deliver for real, set environment variables. No code changes:

.env
MAILINGKIT_PROVIDER=smtp
MAILINGKIT_FROM_EMAIL=no-reply@example.com
MAILINGKIT_FROM_NAME="Example App"
MAILINGKIT_SMTP_HOST=smtp.example.com
MAILINGKIT_SMTP_USERNAME=apikey
MAILINGKIT_SMTP_PASSWORD=change-me

MailingKit.from_env() reads them, picks the provider and sets the default sender. Keyword arguments still win, so MailingKit.from_env(hooks=[...]) adds to what the environment says. See Configuration for every variable.

Not async?

Use SyncMailingKit. It has the same methods and arguments, blocks until the send finishes, and is safe to call from any thread, including Django views and Celery tasks.

The whole API

Most applications use four methods:

MethodWhat it does
send(to=, subject=, html=, text=, ...)Send a message you wrote in code.
send_template(template, data, to=, ...)Render a template with data and send it.
render(template, data)Render without sending, for previews and tests.
validate(message)Return the exact message the provider would receive, or raise.

Every send returns a SendResult with MailingKit's own id, the provider name, the provider_message_id and the number of attempts. Every failure raises a subclass of MailingKitError.

Where next