If you want to send automated emails using Python, then you are on the right page. In this tutorial, we will see python programs to send plain text and HTML emails. You will also learn to send emails with images and PDF attachments. Use the Python scripts in your project to send reminders to your users, team members, or any other purpose. Sending emails is an old-school process now as it consumes time and is also error-prone.
Read this tutorial till the very end, and you will get a good understanding of how you can automate sending emails using Python.
Also Read: 11 Best Python Libraries for Machine Learning
Table of Contents
Getting Started With Sending Emails Using Python
For testing purposes, I will use the Gmail SMTP server to send emails. However, if you wish to use any other email service, that is fine, and the script will work as usual. You can also test the script on a local server, which I will explain later in this tutorial.
Before getting started, please note that I recommend you create a new Gmail account for testing and debugging reasons. Also, you will have to turn on the option of Allow less secure apps to connect with your Gmail account.
Few other things to note are:
1. Don’t add your Gmail account password in the script.
2. Never add your customer’s email in the script as it is pretty sensitive data, and you might want to keep it secure.
3. Don’t name your script as email.py to avoid conflict with the built-in Python module.
I have addressed the above two points in the script, and you will get to know how you can send emails using Python without including any sensitive information in the code.
Also Read: How To Use ArcGIS API for Python and Jupyter Notebooks.
How To Send Text Emails Using Python
Step 1 – Connect to the mail server
There are two classes in the smtplib Python module to connect with the mail server. First, import the smtplib class.
import smtplib
We will connect to the plain old SMTP server using Context Managers, which automatically closes the connection at the end. Context managers ensure efficient resource handling and management. Also, it makes our code more readable and easy to maintain.
Syntax of Context Managers:
with smtplib.SMTP('server', port number) as variable_name: smtp.ehlo() #Identify ourselves with the mail server we are using. smtp.starttls() #Encrypt our connection smtp.ehlo() #Reidentify our connection as encrypted with the mail server
In the smtplib.SMTP() method, you can add these details.
SMTP server address: smtp.gmail.com.
Gmail SMTP port (TLS): 587.
SMTP port (SSL): 465.
SMTP TLS/SSL required: yes.
If you are using any other email service, a quick Google search will give you the necessary information.
After adding the parameters, the method will look like this – smtplib.SMTP('smtp.gmail.com', 587)
Step 2 – Log in with the mail server
Use the smtp.login() function to authenticate your account details.
smtp.login('email', 'password')
Now, it is not a best practice to include your Gmail account details in the script. There are two ways by which you can authenticate your email account without adding sensitive info in your email python script.
The first way is to ask users to specify the password every time the email script is run. The second way is to set up OS environment variables and use them in the script for authentication. In this tutorial, we will implement the first way to keep it simple.
Define global variables to store the following values:
- Sender_Email – Your Gmail address with which you want to send the emails.
- Reciever_Email – Email address of the person to whom you want to send the email.
- Password – Here, you don’t have to store your password. You can use the input() function to specify your Gmail account password at the runtime.
Step 3 – Create your email.
When creating a plain text email from scratch, you need to add the subject as a header and then have a couple of blank lines. After that, you can put the body of the email. For that, I will use Python F-strings, which allows you to embed expressions inside string literals. Do not worry if you don’t understand the syntax right now; I will cover this topic extensively in another tutorial.
Create three global variables to store the subject and body of your email. Use a third variable to concatenate the subject and body of your email using f-strings. Please refer to this code below.
Subject = "Test Email from CodeItBro" Body = "Hi, hope you are doing fine! Stay Home! Stay Safe!" Message = f'Subject: {Subject}\n\n{Body}'
Step 4 – Sending your plain text Email.
In this final step, we have to send the email using the sendmail() method. Here is the syntax of this function:
smtp.sendmail(sender_email, reciever_email, message)
Source Code:
Please find the source code of the complete Python script to send plain emails.
import smtplib Sender_Email = "[email protected]" Reciever_Email = "[email protected]" Password = input('Enter your email account password: ') Subject = "Test Email from CodeItBro" Body = "Hi, hope you are doing fine! Stay Home! Stay Safe!" Message = f'Subject: {Subject}\n\n{Body}' with smtplib.SMTP('smtp.gmail.com', 587) as smtp: smtp.ehlo() smtp.starttls() smtp.ehlo() smtp.login(Sender_Email, Password) smtp.sendmail(Sender_Email, Reciever_Email, Message)
Output:
Testing Using Local Debug Server
To start the local debug server to check your email script, run this command in your terminal.
python -m smtpd -c DebuggingServer -n localhost:1025
After running the local debug server, you must connect to this server on port number 1025.
Now, let’s update our script to test it using the local debug server.
import smtplib Sender_Email = "[email protected]" Subject = "Test Email from CodeItBro" Body = "Hi, hope you are doing fine! Stay Home! Stay Safe!" Message = f'Subject: {Subject}\n\n{Body}' with smtplib.SMTP('localhost', 1025) as server: server.sendmail(Sender_Email, '[email protected]', Message)
Output:
Now that you have understood how to send plain text emails using Python let’s see how to send more complex emails such as HTML emails and attach images and PDF attachments.
Using Python To Send HTML Email With Image and PDF Attachments
Step 1 – Making our code more readable.
We can make our code more readable by using SMTP_SSL class to use secured and encrypted connections right from the beginning. After that, we won’t have to use ehlo() and starttls() method again and again.
Now, you can connect with the Gmail SMTP server using this statement.
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
Step 2 – Using EmailMessage class to create our emails
Moving forward, let’s now improve how we define our email’s content, i.e., subject and body, in our Python script. For that, we can import the EmailMessage class from email.message Python module. EmailMessage is the base class for the email object model and offers the functionality for accessing message bodies.
Using EmailMessage class, we don’t have to use the f-string to concatenate our subject and body. We can create its object to define each component and then send it using the sendmail() function.
Here’s the Python code for it. Have a look and read the comments; you will understand them easily.
import smtplib from email.message import EmailMessage Sender_Email = "[email protected]" Reciever_Email = "[email protected]" Password = input('Enter your email account password: ') newMessage = EmailMessage() #creating an object of EmailMessage class newMessage['Subject'] = "Test Email from CodeItBro" #Defining email subject newMessage['From'] = Sender_Email #Defining sender email newMessage['To'] = Reciever_Email #Defining reciever email newMessage.set_content('Hi, hope you are doing fine! Stay Home! Stay Safe!') #Defining email body with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp: smtp.login(Sender_Email, Password) #Login to SMTP server smtp.send_message(newMessage) #Sending email using send_message method by passing EmailMessage object
Step 3 – Sending attachments with our Python Email
Keep the images and other attachments in the same directory of your Python script. For the starting, let’s see how we can send an image as an attachment.
To send an image as an attachment, we first have to open the file and store its data in a variable. For that, we can use Context Managers as they ensure efficient resource management.
Syntax:
with open('file_name_with_extension', 'file_open_mode') as variable_name: variable_for_storing_image_data = variable_name.read()
Code snippet from our script:
with open('codeitbro-logo.png', 'rb') as f: image_data = f.read()
Before attaching this image to our email, we first have to determine the type of picture. If you want to send a single image attachment, you can do it manually in the script. However, while sending multiple images, you would want Python to detect it for you automatically.
We can use Python built-in module called imghdr. To determine the type of the image, follow this statement. Do not forget to import the imghdr module.
image_type = imghdr.what(f.name)
Now, we can attach the image to our email using the add_attachment() function.
Syntax:
add_attachment(imag_data, maintype='image', subtype=image_type, filename=image_name)
Source Code
import smtplib import imghdr from email.message import EmailMessage Sender_Email = "[email protected]" Reciever_Email = "[email protected]" Password = input('Enter your email account password: ') newMessage = EmailMessage() newMessage['Subject'] = "Check out the new logo" newMessage['From'] = Sender_Email newMessage['To'] = Reciever_Email newMessage.set_content('Let me know what you think. Image attached!') with open('codeitbro-logo.png', 'rb') as f: image_data = f.read() image_type = imghdr.what(f.name) image_name = f.name newMessage.add_attachment(image_data, maintype='image', subtype=image_type, filename=image_name) with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp: smtp.login(Sender_Email, Password) smtp.send_message(newMessage)
Sending Multiple Images As Attachments
Now that you have understood how to attach images as attachments in your email message. Let’s now see how you can send multiple images as attachments in your Python email. You have to create a Python list and store the image file names that you want to attach. After that, you can use Python For loop to open each file and attach it to your email message, as shown in the following code snippet.
files = ['codeitbro-logo.png', 'cat.gif'] for file in files: with open(file, 'rb') as f: image_data = f.read() image_type = imghdr.what(f.name) image_name = f.name newMessage.add_attachment(image_data, maintype='image', subtype=image_type, filename=image_name)
Output:
Sending PDFs As Email Attachments
To send PDFs as email attachments in Python, specify the maintype as application and subtype as octet-stream in the add_attachment() function. Refer to the code snippet below.
Source Code:
import smtplib import imghdr from email.message import EmailMessage Sender_Email = "[email protected]" Reciever_Email = "[email protected]" Password = input('Enter your email account password: ') newMessage = EmailMessage() newMessage['Subject'] = "Check out the new program PDF" newMessage['From'] = Sender_Email newMessage['To'] = Reciever_Email newMessage.set_content('Let me know what you think. Image attached!') files = ['LargeElementArray.pdf'] for file in files: with open(file, 'rb') as f: file_data = f.read() file_name = f.name newMessage.add_attachment(file_data, maintype='application', subtype='octet-stream', filename=file_name) with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp: smtp.login(Sender_Email, Password) smtp.send_message(newMessage)
Output:
Wrapping Up
With this, we sum up our tutorial to send emails using Python. Download Python scripts from our GitHub repository and start sending emails. If you didn’t understand any part of the tutorial, leave your comments, and I will try my best to solve your queries. Stay tuned for more exciting Python tutorials. I will share Python scripts to send personalized emails from a CSV or PDF file in the next post.
If you want me to cover any specific Python tutorial, you can share your suggestions at [email protected].
And, if you are a Python developer and would like to contribute to our community, then do let me know so that I can set up a contributor account for you.