.. module:: aiosmtplib :noindex: The SMTP Client Class ===================== Use the :class:`SMTP` class as a client directly when you want more control over the email sending process than the :func:`send` async function provides. Connecting to an SMTP Server ---------------------------- Initialize a new :class:`SMTP` instance, then await its :meth:`SMTP.connect` coroutine. Initializing an instance does not automatically connect to the server, as that is a blocking operation. .. testcode:: import asyncio from aiosmtplib import SMTP client = SMTP() asyncio.run(client.connect(hostname="127.0.0.1", port=1025)) Connecting over TLS/SSL ~~~~~~~~~~~~~~~~~~~~~~~ .. seealso:: For details on different connection types, see :ref:`connection-types`. If an SMTP server supports direct connection via TLS/SSL, pass ``use_tls=True`` when initializing the SMTP instance (or when calling :meth:`SMTP.connect`). .. code-block:: python smtp_client = aiosmtplib.SMTP(hostname="smtp.gmail.com", port=465, use_tls=True) await smtp_client.connect() STARTTLS connections ~~~~~~~~~~~~~~~~~~~~ .. seealso:: For details on different connection types, see :ref:`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 :meth:`SMTP.starttls` if needed. .. code-block:: python 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 :class:`SMTP` class can also be used as an async context manager, which will automatically connect/disconnect on entry/exit. .. testcode:: 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) asyncio.run(say_hello()) Sending Messages ---------------- :meth:`SMTP.send_message` ~~~~~~~~~~~~~~~~~~~~~~~~~ Use this method to send :py:class:`email.message.EmailMessage` objects, including :py:mod:`email.mime` subclasses such as :py:class:`email.mime.text.MIMEText`. For details on creating :py:class:`email.message.EmailMessage` objects, see `the stdlib documentation examples `_. .. testcode:: 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() asyncio.run(send_with_send_message(mime_message)) Pass :py:class:`email.mime.multipart.MIMEMultipart` objects to :meth:`SMTP.send_message` to send messages with both HTML text and plain text alternatives. .. testcode:: 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("

Hello

", "html", "utf-8")) async def send_multipart_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() asyncio.run(send_multipart_message(message)) :meth:`SMTP.sendmail` ~~~~~~~~~~~~~~~~~~~~~ Use :meth:`SMTP.sendmail` to send raw messages. Note that when using this method, you must format the message headers yourself. .. testcode:: 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() asyncio.run(send_with_sendmail()) 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 :meth:`SMTP.send_message` tasks in parallel (i.e. with :py:func:`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 (:class:`SMTP` instances) and splitting the work between them.