Send SMTP email with Python (using SMTPLib)

How to send emails with Python's built-in SMTP client and MailSlurp mail servers.

python smtp

Python is the language that can do it all - including SMTP email! Using the in-built smtplib library we can setup outbound email sending in Python to external SMTP servers. Let us demonstrate.

What is SMTP and how does it work?

Firstly, a quick overview of SMTP and how emails work. SMTP (simple mail transfer protocol) describe the sending and receiving of email over TCP - typically on the ports 25, 2525, 465 or 587. Each email address (such as @gmail.com) has an underlying SMTP server that runs on the domain (smtp.gmail.com for instance) and listens for incoming emails. When we wish to email an address provided by the server we can connect via SMTP in Python and submit a message.

Configuring SMTPLib

To use Python to send SMTP emails we first need to import and configure the batteries included smtplib library. In a new python file add:

from smtplib import SMTP

Once imported you can open a new connection like so:

with SMTP(host='smtp.gmail.com', port=465) as smtp:
    smtp.sendmail(from_addr='from@address.com', to_addrs=['to@address.com'], msg='Your message')
    smtp.quit()

For each email you wish to send you will need to connect to the underlying SMTP server or use your own SMTP server to pass the emails on for you. When using your own SMTP server you will want to create authentication so that only you can send from it.

Using authentication

Say you have created an SMTP server with MailSlurp, you can access the server using your username and password for the account hosted on a domain and port:

Protocol Host Port TLS Description
SMTP mx.mailslurp.com 2525 false SMTP server

In code you can use the MailSlurp SDK to obtain these details with the inbox_controller.get_imap_smtp_access() method.

# get smtp imap access
smtp_access = inbox_controller.get_imap_smtp_access(inbox_id=inbox1.id)
msg = "Subject: Test subject\r\n\r\nThis is the body"

with SMTP(host=smtp_access.smtp_server_host, port=smtp_access.smtp_server_port) as smtp:
    smtp.login(user=smtp_access.smtp_username, password=smtp_access.smtp_password)
    smtp.sendmail(from_addr=inbox1.email_address, to_addrs=[inbox2.email_address], msg=msg)
    smtp.quit()

SMTP servers provide several authentication methods but LOGIN and PLAIN are two common methods.

Sending email content

To send SMTP emails in Python you must construct and email body. The body of an email begins with lines of headers that are key value pairs and then a body separated by a new line. For instance: msg = "Subject: Test subject\r\n\r\nThis is the body".

Testing emails with MailSlurp

To test if your Python application is sending emails correctly or to run your own SMTP server try MailSlurp. MailSlurp provides unlimited disposable (or permanent) email mailboxes that can be connected to using Python and SMTP to send emails. Let us use MailSlurp and Pytest to demonstrate:

import os
# get an api key at https://app.mailslurp.com/sign-up
import mailslurp_client
from smtplib import SMTP
from mailslurp_client import CreateInboxDto

api_key = os.environ.get('API_KEY')
assert api_key is not None

# create a mailslurp configuration
configuration = mailslurp_client.Configuration()
configuration.api_key['x-api-key'] = api_key


class Test_MailSlurp_SDK:
    """
    Can send email with SMTP
    """
    def test_can_send_with_smtp(self):
        with mailslurp_client.ApiClient(configuration) as api_client:
            inbox_controller = mailslurp_client.InboxControllerApi(api_client)
            inbox1 = inbox_controller.create_inbox_with_options(CreateInboxDto(inbox_type="SMTP_INBOX"))
            inbox2 = inbox_controller.create_inbox()
            assert "@mailslurp.mx" in inbox1.email_address

            # get smtp imap access
            smtp_access = inbox_controller.get_imap_smtp_access(inbox_id=inbox1.id)
            msg = "Subject: Test subject\r\n\r\nThis is the body"

            with SMTP(host=smtp_access.smtp_server_host, port=smtp_access.smtp_server_port) as smtp:
                smtp.login(user=smtp_access.smtp_username, password=smtp_access.smtp_password)
                smtp.sendmail(from_addr=inbox1.email_address, to_addrs=[inbox2.email_address], msg=msg)
                smtp.quit()

            wait_for_controller = mailslurp_client.WaitForControllerApi(api_client)
            email = wait_for_controller.wait_for_latest_email(inbox_id=inbox2.id)
            assert "Test subject" in email.subject

More information

To read more about SMTP email sending in Python consult the smtplib docs or see the MailSlurp Python developer page.

Ready to dive in?Start building email applications today.