Overview¶
aiosmtplib is an asynchronous SMTP client for use with asyncio.
Quickstart¶
import asyncio
from email.mime.text import MIMEText
import aiosmtplib
loop = asyncio.get_event_loop()
smtp = aiosmtplib.SMTP(hostname="127.0.0.1", port=1025, loop=loop)
loop.run_until_complete(smtp.connect())
message = MIMEText("Sent via aiosmtplib")
message["From"] = "root@localhost"
message["To"] = "somebody@example.com"
message["Subject"] = "Hello World!"
loop.run_until_complete(smtp.send_message(message))
Requirements¶
Python 3.5.2+, compiled with SSL support, is required.
Connecting to an SMTP Server¶
Initialize a new SMTP
instance, then await its SMTP.connect()
coroutine. Initializing an instance does not automatically connect to the
server, as that is a blocking operation.
client = SMTP()
loop = asyncio.get_event_loop()
loop.run_until_complete(client.connect(hostname="localhost", port=25))
Connecting over TLS/SSL¶
If an SMTP server supports direct connection via TLS/SSL, pass use_tls=True
when initializing the SMTP instance (or when calling SMTP.connect()
).
loop = asyncio.get_event_loop()
smtp = aiosmtplib.SMTP(hostname="smtp.gmail.com", port=465, loop=loop, use_tls=True)
loop.run_until_complete(smtp.connect())
STARTTLS connections¶
Many SMTP servers support the STARTTLS extension over port 587. When using
STARTTLS, the initial connection is made over plaintext, and after connecting
a STARTTLS command is sent which initiates the upgrade to a secure connection.
To connect to a server that uses STARTTLS, set use_tls
to False
when
connecting, and call SMTP.starttls()
on the client.
loop = asyncio.get_event_loop()
smtp = aiosmtplib.SMTP(hostname="smtp.gmail.com", port=587, loop=loop, use_tls=False)
loop.run_until_complete(smtp.connect())
loop.run_until_complete(smtp.starttls())
Connecting via async context manager¶
Instances of the SMTP
class can also be used as an async context
manager, which will automatically connect/disconnect on entry/exit.
async def send_message():
message = MIMEText("Sent via aiosmtplib")
message["From"] = "root@localhost"
message["To"] = "somebody@example.com"
message["Subject"] = "Hello World!"
async with aiosmtplib.SMTP(hostname="127.0.0.1", port=1025, loop=loop):
await smtp.send_message(message)
loop.run_until_complete(send_message())
Sending Messages¶
SMTP.send_message()
¶
This is the simplest API, and is the recommended way to send messages, as it
makes it easy to set headers correctly and handle multi part messages. For
details on creating email.message.Message
objects, see the
stdlib documentation examples.
Use SMTP.send_message()
to send email.message.Message
objects,
including email.mime
subclasses such as
email.mime.text.MIMEText
.
from email.mime.text import MIMEText
message = MIMEText("Sent via aiosmtplib")
message["From"] = "root@localhost"
message["To"] = "somebody@example.com"
message["Subject"] = "Hello World!"
loop = asyncio.get_event_loop()
loop.run_until_complete(smtp.send_message(message))
Pass email.mime.multipart.MIMEMultipart
objects to
SMTP.send_message()
to send messages with both HTML text and plain text
alternatives.
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
message = MIMEMultipart("alternative")
message["From"] = "root@localhost"
message["To"] = "somebody@example.com"
message["Subject"] = "Hello World!"
message.attach(MIMEText("hello", "plain", "utf-8"))
message.attach(MIMEText("<html><body><h1>Hello</h1></body></html>", "html", "utf-8"))
loop = asyncio.get_event_loop()
loop.run_until_complete(smtp.send_message(message))
SMTP.sendmail()
¶
Use SMTP.sendmail()
to send raw messages. Note that when using this
method, you must format the message headers yourself.
sender = "root@localhost"
recipients = ["somebody@example.com"]
message = """To: somebody@example.com
From: root@localhost
Subject: Hello World!
Sent via aiosmtplib
"""
loop = asyncio.get_event_loop()
loop.run_until_complete(smtp.sendmail(sender, recipients, message))
Timeouts¶
All commands accept a timeout
keyword argument of a numerical value in
seconds. This value is used for all socket operations, and will raise
SMTPTimeoutError
if exceeded. Timeout values passed to
SMTP.__init__()
or SMTP.connect()
will be used as the default value
for commands executed on the connection.
The default timeout is 60 seconds.
Parallel Execution¶
SMTP is a sequential protocol. Multiple commands must be sent to send an
email, and they must be sent in the correct sequence. As a consequence of
this, executing multiple SMTP.sendmail()
tasks in parallel (i.e. with
asyncio.gather()
) is not any more efficient than executing in sequence,
as the client must wait until one mail is sent before beginning the next.
If you have a lot of emails to send, consider creating multiple connections
(SMTP
instances) and splitting the work between them.
Bug reporting¶
Bug reports (and feature requests) are welcome via Github issues.