You are on the right page if you want to send automated emails using Python. This tutorial will show 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 and team members or for any other purpose. Sending emails is an old-school process as it consumes time and is error-prone.
Read this tutorial until the end, and you will understand how to automate sending emails using Python.
Getting Started With Sending Emails Using Python
I will use the Gmail SMTP server to send emails for testing purposes. 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 to Allow less secure apps to connect with your Gmail account.
A few other things to note are:
1. Don’t add your Gmail account password to the script.
2. Never add your customer’s email in the script, as it is 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 learn how to send emails using Python without including sensitive information in the code.
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.
A quick Google search will give you the necessary information if you use any other email service.
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')
Including your Gmail account details in the script is not a best practice. You can authenticate your email account without adding sensitive info in your Python script in two ways.
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. This tutorial 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 runtime.
Step 3 – Create your email.
When creating a plain text email from scratch, add the subject as a header and then have a few 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 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 the 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 must 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 = "emailpythontest12345@gmail.com" Reciever_Email = "codeitbro@gmail.com" 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
Run this command in your terminal to start the local debug server to check your email script.
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 = "emailpythontest12345@gmail.com" 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, 'codeitbro@gmail.com', 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 – Make our code more readable.
We can make our code more readable by using the SMTP_SSL class to use secured and encrypted connections from the beginning. After that, we won’t have to repeatedly use the ehlo() and starttls() methods.
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 the EmailMessage class to create our emails
Moving forward, let’s 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 the 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 = "emailpythontest12345@gmail.com" Reciever_Email = "codeitbro@gmail.com" 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 a start, let’s see how we can send an image as an attachment.
To send an image as an attachment, we must 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 must determine the type of picture. If you want to send a single image attachment, you can do it manually in the script. However, you would want Python to detect them automatically while sending multiple images.
We can use a 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 = "emailpythontest12345@gmail.com" Reciever_Email = "codeitbro@gmail.com" 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 see how you can send multiple images as attachments in your Python email.
You must create a Python list and store the image file names 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 = "emailpythontest12345@gmail.com" Reciever_Email = "codeitbro@gmail.com" 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. In the next post, I will share Python scripts to send personalized emails from a CSV or PDF file.
If you want me to cover any specific Python tutorial, you can share your suggestions at codeitbro@gmail.com.
If you are a Python developer and would like to contribute to our community, please let me know so I can set up a contributor account.