Sending emails using python

April 20, 2018, 11:56 p.m.

It can be really useful to have a script that will send automated emails using python. For instance if you are running a script and you want to be alerted when certain kinds of events occur. Fortunately, there is an easy way to do this in Python.

In order to send email messages, you need access to an SMTP server. You can just use the SMTP server settings of your existing email provider. The code used below has been configured to make use of gmail's SMTP servers. You may need to modify some settings to get it to work for other email providers.

Configuring Gmail

By default, Gmail has a setting which will not allow python to log into its SMTP server. It is a security feature that prevents unsafe logins. If you are concerned about the safety of your email account, then I might recommend setting up a dummy Gmail account just for the purposes of sending emails with python. You can change the Gmail setting by performing the following steps.

Credentials

We will store the credentials for your email account in a separate json file, rather than hard-coding these in python. This will minimize the risk of accidentally exposing your sensitive information in a public place like Github if you use git version control for your code.

NOTE : Your login details will be in plain text. So do not place this json file in a publically accessible location.

Call the file something like credentials.json and the contents of this file should be as follows:

{
    "smtp_host": "smtp.gmail.com",
    "smtp_port": 587,
    "user": "MYEMAIL@gmail.com",
    "password": "MYPASSWORD"
}

Replace MYEMAIL, MYPASSWORD with your own details for your account.

Supporting Functions

We will create two functions. One to connect to the SMTP server, and another one to send emails using that connection to the server.

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText  # for sending text-only messages
from email.mime.image import MIMEImage # for image attachments
# from email.mime.image import MIMEAudio # for audio attachments
import smtplib

def connect2server(user, password, host, port):
    """ Connect to an SMTP server. Note, this function assumes that the SMTP
        server uses TTLS connection """
    server = smtplib.SMTP(host=host,port=port)
    server.starttls()
    server.login(user=user, password=password)
    return server

def send_message(server, user, to, subject="", body="", attachments=[]):
    """ Given a server client object it sends an email

    Args:
        server: connection to the server object returned by connect2server()
        user:   your email eg: "email@domain.com"
        to:     list of emails to send to
        subject: subject heading
        body:    the text of the body of the email
        attachments: list of paths to image files to upload
    """
    # BUILD MESSAGE OBJECT
    msg = MIMEMultipart()
    msg['From'] = user
    msg['To'] = ", ".join(to)
    msg['Subject'] = subject
    msg.attach(MIMEText(body, 'plain'))

    # if attachment is not None:
    for attachment in attachments:
        msg.attach(MIMEImage(open(attachment, mode="rb").read()))

    # SEND MESSAGE.
    return server.sendmail(user, to, msg.as_string())

Making use of the functions to send emails

Below is an example of putting all these things together to send emails.

import json

# GET CREDENTIALS - from json file
with open("credentials.json", mode="r") as f:
    credentials = json.load(f)

USER = credentials["user"]
PASSWORD = credentials["password"]
HOST = credentials["smtp_host"]
PORT = credentials["smtp_port"]

# CONNECT TO SERVER
server = connect2server(user=USER,password=PASSWORD,host=HOST,port=PORT)

# SEND MESSAGE
send_message(server=server, user=USER,
    to=["tony.stark@avengers.com", "starlord@guardians.com"],
    subject="funny images",
    body="check out these funny pictures of Groot",
    attachments=["/tmp/drunk_groot.jpg", "/tmp/groot_on_fire.jpg"])

# CLOSE CONNECTION TO SERVER
server.quit()

Credits

This tutorial is based on Esther Vaati's great tutorial. But I tried to make things simpler and more modular by wrapping things in functions. However, if you wish to implement some more advanced features such as sending HTML formatted emails, then I would suggest going to Esther's tutorial.

Comments

Note you can comment without any login by:

  1. Typing your comment
  2. Selecting "sign up with Disqus"
  3. Then checking "I'd rather post as a guest"