How to Send Beautiful Emails With Python — The Essential Guide

How to Send Beautiful Emails With Python — The Essential Guide

Send stylized emails with attachments with Python. To multiple recipients.

Sending emails through programming languages like Python has many use cases. For example, you might want to manage a mailing list without paying monthly fees, or use it to notify you when something breaks in production code. Today you’ll learn how to easily send beautiful emails — to multiple recipients. Attachments included.

To achieve this, we’ll use Python’s smtplib. SMTP stands for Simple Mail Transfer Protocol, for you nerds out there. It is a simple library that allows us to send emails. We’ll also use the email library for formatting purposes. Both are built into Python, so there’s no need to install anything.

Here’s today’s agenda:

  • Gmail setup
  • Sending simple emails
  • Sending emails to multiple recipients
  • Sending attachments
  • Sending HTML formatted emails
  • Conclusion

It’s a lot to cover, so let’s get straight to it.


Gmail setup

I’m assuming you have two-factor authentication enabled on your Gmail account. If not, you should. We’ll have to generate a password that Python script will use to log into your account and send emails.

It’s a straightforward step to do. Just click on this URL, and you’ll be presented with a screen like this:

Image by author

Image by author

You won’t see the “Python Email” row, however. Just click on the Select app dropdown, and then on Other (Custom name). Enter a name (arbitrary), and click on the Generate button.

That’s it! A modal window like this will pop up:

Image by author

Image by author

Just make to save the password somewhere safe.

You can now open up a code editor (or notebook) and create a Python file. Here are the library imports and variable declarations for email and password:

import smtplib
from email.message import EmailMessage

EMAIL_ADDRESS = 'your_email_address'
EMAIL_PASSWORD = 'your_app_password'

Keep in mind —EMAIL_ADDRESS variable should contain your actual email address, and the EMAIL_PASSWORD should contain the app password generated seconds ago. There is a more robust and secure way to do this – with environment variables, but that’s beyond the scope of this article.

You’re ready to send your first email now.


Sending simple emails

Here’s the part you’ve been waiting for. A couple of steps are required before you can send emails, and those are listed below:

  1. Make an instance of the EmailMessage class
  2. Specify From, To, and Subject— you guess which one is for what
  3. Set the content of the email — the message itself
  4. Use smtplib to establish a secure connection (SSL) and login into your email account
  5. Send the email

It sounds like a lot of work, but it boils down to less than ten code lines. Here’s the snippet:

msg = EmailMessage()
msg['Subject'] = 'This is my first Python email'
msg['From'] = EMAIL_ADDRESS 
msg['To'] = EMAIL_ADDRESS 
msg.set_content('And it actually works')


with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
    smtp.login(EMAIL_ADDRESS, EMAIL_PASSWORD) 
    smtp.send_message(msg)

As you can see, I’ve set the From and To fields to the same value. It’s not something you would usually do, but is essential for testing purposes. And here’s the email I’ve received seconds after:

Image by author

Image by author

Let’s see how to send emails to multiple recipients next.


Sending emails to multiple recipients

If you understood the previous section, you’ll understand this one. There’s only a single thing you have to change.

In the msg['To'], instead of specifying an email address you want to send to (as with the previous example), you will have to specify a list of emails.

Here’s the code:

msg = EmailMessage()
msg['Subject'] = 'This is my email for multiple people'
msg['From'] = EMAIL_ADDRESS 
msg['To'] = ['[email protected]', '[email protected]']
msg.set_content('It works!')


with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
    smtp.login(EMAIL_ADDRESS, EMAIL_PASSWORD) 
    smtp.send_message(msg)

Can you spot the difference? Sending to multiple recipients is easier than expected, as you don’t have to iterate through the list manually. Let’s continue with the email attachments.


Sending attachments

Sending attachments is a bit weird until you get the gist of it. You have to open every attachment with Python’s with open syntax, and use the add_attachment method from the EmailMessage class to, well, add it.

In the example below, this method was used to send a PDF document. Here’s the code:

msg = EmailMessage()
msg['Subject'] = 'This is my email with PDF attachment'
msg['From'] = EMAIL_ADDRESS 
msg['To'] = EMAIL_ADDRESS 
msg.set_content('See below')


with open('ExampleDoc.pdf', 'rb') as pdf:
    msg.add_attachment(pdf.read(), maintype='application', subtype='octet-stream', filename=pdf.name)
    
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
    smtp.login(EMAIL_ADDRESS, EMAIL_PASSWORD) 
    smtp.send_message(msg)

And here’s the email I’ve got a couple of seconds later:

Image by author

Image by author

Awesome! Let’s see how to create customized emails next!


Sending HTML formatted emails

You can cross inbound from your list if you intend to send pure textual, unstyled, and otherwise ugly emails. That’s where HTML and CSS come into play.

Code-wise it’s nearly identical thing as in the previous section. The only difference is the email content. This time you’ll use the set_contentmethod from the EmailMessage class to write the HTML. CSS styles are set inline.

Here’s what I’ve managed to design in a couple of minutes:

msg = EmailMessage()
msg['Subject'] = 'Here is my newsletter'
msg['From'] = EMAIL_ADDRESS 
msg['To'] = EMAIL_ADDRESS
msg.set_content('''
<!DOCTYPE html>
<html>
    <body>
        <div style="background-color:#eee;padding:10px 20px;">
            <h2 style="font-family:Georgia, 'Times New Roman', Times, serif;color#454349;">My newsletter</h2>
        </div>
        <div style="padding:20px 0px">
            <div style="height: 500px;width:400px">
                <img src="https://dummyimage.com/500x300/000/fff&text=Dummy+image" style="height: 300px;">
                <div style="text-align:center;">
                    <h3>Article 1</h3>
                    <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. A ducimus deleniti nemo quibusdam iste sint!</p>
                    <a href="#">Read more</a>
                </div>
            </div>
        </div>
    </body>
</html>
''', subtype='html')


with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
    smtp.login(EMAIL_ADDRESS, EMAIL_PASSWORD) 
    smtp.send_message(msg)
Image by author

Image by author

Not great, but an improvement from what we had before. And that’s just enough for today. Let’s wrap things up in the next section.


Parting words

Sending emails in Python is easy. Gmail configuration enables you to send them right from your machine — there’s no need to upload anything to a live server. And that’s great if you ask me. A couple of years ago, when I first started sending emails through PHP, the localhost was not an option (according to my experience).

You have seen a bunch of new concepts today — from sending emails to front-end technologies. It’s just enough to get you started, and the web is full of more advanced guides.

Thanks for reading.