Sending Emails using Python 3.6+
A Python 3.6 feature that has flown under the radar is the revamped email
package.
In this post we will explore email
and walk through an example of creating and sending an email using the Python Standard Library.
Exploring email
The email
package is comprised of three major components:
email.message
- Representation of an email messageemail.parser
- Used to parse email messagesemail.generator
- Used to generate MIME documents
To send emails we have to interact with email.message.EmailMessage
; this class provides a high level abstraction of an email message. Everytime we want to write a new email, we create a new instance of the object:
from email.message import EmailMessage
msg = EmailMessage()
We can then modify msg
using a dictionary-like interface:
msg['From'] = 'alysivji@gmail.com'
msg['To'] = 'alysivji+test@gmail.com'
msg['Subject'] = 'Test Email'
And set the email body using .set_content()
:
msg.set_content('Email body')
For HTML emails, we will need to specify subtype=html
:
msg.set_content('HTML email with <a href="https://alysivji.github.io">link</a>', subtype='html')
Sending Plain Text Emails
We can leverage smtplib
to send messages programatically from Python. I used this article as a template to get started.
# send_email.py
from email.headerregistry import Address
from email.message import EmailMessage
import os
import smtplib
# Gmail details
email_address = os.getenv('GMAIL_ADDRESS', None)
email_password = os.getenv('GMAIL_APPLICATION_PASSWORD', None)
# Recipent
to_address = (
Address(display_name='Aly Sivji', username='alysivji', domain='gmail.com'),
)
def create_email_message(from_address, to_address, subject, body):
msg = EmailMessage()
msg['From'] = from_address
msg['To'] = to_address
msg['Subject'] = subject
msg.set_content(body)
return msg
if __name__ == '__main__':
msg = create_email_message(
from_address=email_address,
to_address=to_address,
subject='Hello World',
body="Test sending the body.",
)
with smtplib.SMTP('smtp.gmail.com', port=587) as smtp_server:
smtp_server.ehlo()
smtp_server.starttls()
smtp_server.login(email_address, email_password)
smtp_server.send_message(msg)
print('Email sent successfully')
Set a couple of environment variables before running the script:
$ export GMAIL_ADDRESS='alysivji@gmail.com'
$ export GMAIL_APPLICATION_PASSWORD='[INSERT PASSWORD HERE]'
$ python send_email.py
Email sent successfully
Let's check our email
Perfect
Notes
- Emails are represented using Address
- You will need to look up the SMTP details of your email provider, this is easily done by searching for "[Email Provider] SMTP" on Google.
- Gmail:
smtp.gmail.com
port587
- Yahoo:
smtp.mail.yahoo.com
port587
- Live:
smtp.live.com
port25
- Gmail:
- Two-factor Authentication complicates this process; we will need an application password to send emails. Setting up Application Password for a Google Account.
- We can use
smtplib.SMTP()
as a context manager. I covered context managers in a previous post.
Sending HTML Emails
In order to send HTML emails, we need to specify the MIME type as text/html
.
It is considered good practice to send a text/plain
version along with a text/html
version for the small minority of users who have disabled HTML emails. Also for our Pine users, can't forget about them!
We can attach additional MIME types with the .add_alternative()
function.
# send_html_email.py
from email.headerregistry import Address
from email.message import EmailMessage
import os
import smtplib
# Gmail details
email_address = os.getenv('GMAIL_ADDRESS', None)
email_password = os.getenv('GMAIL_APPLICATION_PASSWORD', None)
# Recipent
to_address = (
Address(display_name='Aly Sivji', username='alysivji', domain='gmail.com'),
)
def create_email_message(from_address, to_address, subject,
plaintext, html=None):
msg = EmailMessage()
msg['From'] = from_address
msg['To'] = to_address
msg['Subject'] = subject
msg.set_content(plaintext)
if html is not None:
msg.add_alternative(html, subtype='html')
return msg
HTML_MESSAGE = """\
<p>
HTML Version!
</p>
<p>
Link to <a href="https://alysivji.github.io">my blog</a>!
</p>
"""
if __name__ == '__main__':
msg = create_email_message(
from_address=email_address,
to_address=to_address,
subject='Hello World',
plaintext="Plain text version.",
html=HTML_MESSAGE
)
with smtplib.SMTP('smtp.gmail.com', port=587) as smtp_server:
smtp_server.ehlo()
smtp_server.starttls()
smtp_server.login(email_address, email_password)
smtp_server.send_message(msg)
print('Email sent successfully')
$ export GMAIL_ADDRESS='alysivji@gmail.com'
$ export GMAIL_APPLICATION_PASSWORD='[INSERT PASSWORD HERE]'
$ python send_html_email.py
Email sent successfully
Looks good!
Additional Resources
email
examples from the Standard Library
Comments