Skip to main content

Email delivery for asyncio.

Project description

Mailers for asyncio


pip install mailers

If you plan to use FileTransport you would also need to install aiofiles extra:

pip install mailers[aiofiles]

Or install all optional dependencies at once:

pip install mailers[full]


The package uses two main concepts: mailers and transports. The mailer is a class which abstracts you from the underlying transport and the transport does the actual message delivery.

from mailers import EmailMessage, configure, send_mail

    'default': 'smtp://user:password@localhost:25?timeout=2'

message = EmailMessage(
    to='user@localhost', from_address='from@localhost',
    subject='Hello', text_body='World!'
await send_mail('user@localhost', message)

Or if you prefer more control on what is going one, take this more verbose path:

from mailers import Mailer, SMTPTransport, EmailMessage

mailer = Mailer(SMTPTransport('localhost', 25))

message = EmailMessage(
    to='user@localhost', from_address='from@localhost',
    subject='Hello', text_body='World!'
await mailer.send(message)


The packages exports some utility methods to simplify the work: configure and send_mail.

configure methods allows to configure multiple mailers and bind URL specs at once.

from mailers import configure

        'default': 'smtp://localhost',
        'admin': 'smtp://localhost'   
        'myproto': 'myproto.ImplementationClass'            

In case you have multiple mailers, the send_mail shortcut accepts mailer argument to specify the mailer to use:

send_mail(to, message, mailer='admin')

When you dont't set mailer argument, the function will use mailer with name default.

Compose messages

The arguments and methods of EmailMessage class are self-explanatory so here is some basic example:

from mailers import EmailMessage, Attachment

message = EmailMessage(
    text_body='Hello world!',
    html_body='<b>Hello world!</b>',
        Attachment('CONTENTS', 'file.txt', 'text/plain'),    

# attachments can be added on demand:

with open('file.txt', 'r') as f:
    message.attach(,, 'text/plain')

    # alternatively
        Attachment(,, 'text/plain')

cc, bcc, to, reply_to can be either strings or lists of strings.

A note about attachments

Accessing files is a blocking operation. You may want to use aiofiles or alternate library which reads files in non-blocking mode.

This package does not implement direct access to files at moment. This is something to do at later stage.


Preinstalled transports

All transport classes can be found in mailers.transports module.

Class Example URL Description
SMTPTransport smtp://user:pass@hostname:port?timeout=&use_tls=1 Sends mails using SMTP protocol.
InMemoryTransport not available Stores sent messages in the local variable. See an example below.
FileTransport file:///path/to/directory Writes sent messages into directory.
NullTransport null:// Does not perform any sending.
StreamTransport not available Writes message to an open stream. See an example below.
ConsoleTransport console:// Prints messages into stdout.
GMailTransport gmail://username:password Sends via GMail.
MailgunTransport mailgun://username:password Sends via Mailgun.

Special notes


InMemoryTransport takes a list and writes outgoing mail into it. Read this list to inspect the outbox.

from mailers import InMemoryTransport, EmailMessage

message = EmailMessage()
mailbox = []
transport = InMemoryTransport(mailbox)
await transport.send(message)

assert message in mailbox


Writes messages into the open stream.

from mailers import StreamTransport, EmailMessage
from io import TextIO

message = EmailMessage()

transport = StreamTransport(output=TextIO())
await transport.send(message)

output is any IO compatible object.

Custom transports.

Each transport must implement async def send(self, message: EmailMessage) -> None method. Preferably, inherit from BaseTransport class:

from mailers import BaseTransport, Mailer, EmailMessage

class PrintTransport(BaseTransport):
    async def send(self, message: EmailMessage) -> None

mailer = Mailer(PrintTransport())

In order to make your transport to accept EmailURL instances, your transport class has to implement from_url class method:

from mailers import BaseTransport, EmailMessage, EmailURL

class PrintTransport(BaseTransport):
    def from_url(cls, url: EmailURL) -> "PrintTransport":
        return cls()

Add custom transport protocols.

Once you build a custom transport you can add it's URL to enable URL-based configurations.

from mailers import Transports, Mailer

Transports.bind_url('myprotocol', 'my.transport.Name')

mailer = Mailer('myprotocol://')

Note that the transport must to implement from_url method to accept URL parameters. Otherwise it will be constructed without any arguments passed to the __init__ method.

Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for mailers, version 0.0.1
Filename, size File type Python version Upload date Hashes
Filename, size mailers-0.0.1.tar.gz (12.1 kB) File type Source Python version None Upload date Hashes View
Filename, size mailers-0.0.1-py3-none-any.whl (11.4 kB) File type Wheel Python version py3 Upload date Hashes View

Supported by

AWS AWS Cloud computing Datadog Datadog Monitoring Facebook / Instagram Facebook / Instagram PSF Sponsor Fastly Fastly CDN Google Google Object Storage and Download Analytics Huawei Huawei PSF Sponsor Microsoft Microsoft PSF Sponsor NVIDIA NVIDIA PSF Sponsor Pingdom Pingdom Monitoring Salesforce Salesforce PSF Sponsor Sentry Sentry Error logging StatusPage StatusPage Status page