The SMTP Client Class¶
Use the SMTP
class as a client directly when you want more control
over the email sending process than the send()
async function provides.
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.
import asyncio
from aiosmtplib import SMTP
client = SMTP()
event_loop = asyncio.get_event_loop()
event_loop.run_until_complete(client.connect(hostname="127.0.0.1", port=1025))
Connecting over TLS/SSL¶
For details on different connection types, see Connection Types.
If an SMTP server supports direct connection via TLS/SSL, pass use_tls=True
when initializing the SMTP instance (or when calling SMTP.connect()
).
smtp_client = aiosmtplib.SMTP(hostname="smtp.gmail.com", port=465, use_tls=True)
await smtp_client.connect()
STARTTLS connections¶
For details on different connection types, see Connection Types.
By default, if the server advertises STARTTLS support, aiosmtplib will
upgrade the connection automatically. Setting use_tls=True
for STARTTLS
servers will typically result in a connection error.
To opt out of STARTTLS on connect, pass start_tls=False
. You may then
manually call SMTP.starttls()
if needed.
smtp_client = aiosmtplib.SMTP(
hostname="smtp.gmail.com",
port=587,
start_tls=False,
use_tls=False,
)
await smtp_client.connect()
await smtp_client.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.
import asyncio
from email.message import EmailMessage
from aiosmtplib import SMTP
async def say_hello():
message = EmailMessage()
message["From"] = "root@localhost"
message["To"] = "somebody@example.com"
message["Subject"] = "Hello World!"
message.set_content("Sent via aiosmtplib")
smtp_client = SMTP(hostname="127.0.0.1", port=1025)
async with smtp_client:
await smtp_client.send_message(message)
event_loop = asyncio.get_event_loop()
event_loop.run_until_complete(say_hello())
Sending Messages¶
SMTP.send_message()
¶
Use this method to send email.message.EmailMessage
objects, including
email.mime
subclasses such as email.mime.text.MIMEText
.
For details on creating email.message.Message
objects, see the
stdlib documentation examples.
import asyncio
from email.mime.text import MIMEText
from aiosmtplib import SMTP
mime_message = MIMEText("Sent via aiosmtplib")
mime_message["From"] = "root@localhost"
mime_message["To"] = "somebody@example.com"
mime_message["Subject"] = "Hello World!"
async def send_with_send_message(message):
smtp_client = SMTP(hostname="127.0.0.1", port=1025)
await smtp_client.connect()
await smtp_client.send_message(message)
await smtp_client.quit()
event_loop = asyncio.get_event_loop()
event_loop.run_until_complete(send_with_send_message(mime_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"))
smtp_client = SMTP(hostname="127.0.0.1", port=1025)
event_loop.run_until_complete(smtp_client.connect())
event_loop.run_until_complete(smtp_client.send_message(message))
event_loop.run_until_complete(smtp_client.quit())
SMTP.sendmail()
¶
Use SMTP.sendmail()
to send raw messages. Note that when using this
method, you must format the message headers yourself.
import asyncio
from aiosmtplib import SMTP
sender = "root@localhost"
recipients = ["somebody@example.com"]
message = """To: somebody@example.com
From: root@localhost
Subject: Hello World!
Sent via aiosmtplib
"""
async def send_with_sendmail():
smtp_client = SMTP(hostname="127.0.0.1", port=1025)
await smtp_client.connect()
await smtp_client.sendmail(sender, recipients, message)
await smtp_client.quit()
event_loop = asyncio.get_event_loop()
event_loop.run_until_complete(send_with_sendmail())
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 send()
,
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.send_message()
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.