Python smtplib module can be used to send emails in the Python program. It’s a very common requirement in software applications and smtplib provides SMTP protocol client to send emails.
1. Sending Email in Python
Let’s develop a program to send email in python.
- We will use a template file as well which we will show in the next section and which we will use while we’re sending the emails.
- We will also pick the name and email of the person we want to send the email to, from a text file we make
That sounds better than just a simple task of sending email to static emails. Let’s get started.
1.1) Defining File containing emails
We will start defining a simple file which will contain the names and emails of people we want to send the email to. Let’s look at the format of the file we use:
1 2 3 4 |
contribute contribute@example.com shubham shubham@example.com |
This file just contains the name of the person in lowercase characters followed by the email of the person. We use lowercase characters in the name as we will leave it to Python’s capabilities to convert it to proper capital words.
We will call the above file as contacts.txt
.
1.2) Defining the Template
When we send an email to users, we usually want to personalize the email with their name so that they feel specifically asked for. We can achieve this by using a template where we can embed the user’s name so that each user receives an email with their name embedded in it.
Let’s look at the template we are going to use for the program:
1 2 3 4 5 6 |
Dear ${USER_NAME}, This is an email which is sent using Python. Isn't that great?! Have a great day ahead! Cheers |
Notice the template string ${USER_NAME}
. This string will be replaced with the name which is contained in the text file we last created.
We will call the above file as message.txt
.
1.3) Parsing Emails from File
We can parse the text file by opening it in the r
mode and then iterating through each line of the file:
1 2 3 4 5 6 7 8 9 10 |
def get_users(file_name): names = [] emails = [] with open(file_name, mode="r", encoding='utf-8') as user_file: for user_info in user_file: names.append(user_info.split()[0]) emails.append(user_infouser.split()[1]) return names, emails |
With this Python function, we Return two lists names
, emails
which contains names and emails of users from the file we pass to it. These will be used in the email template message body.
1.4) Getting the Template Object
It is time we get the template object in which we make use of the template file we created by opening it in the r
mode and parsing it:
1 2 3 4 5 6 |
def parse_template(file_name): with open(file_name, 'r', encoding='utf-8') as msg_template: msg_template_content = msg_template.read() return Template(msg_template_content) |
With this function, we get a Template object which comprises of the contents of the file we specified by filename.
2. How sending emails work?
Till now, we’re ready with the data we want to send in the email and the receiver’s emails. Here, let us look at the steps we need to complete to be ready to send the emails:
- Setup the SMTP Connection and Account credentials for login
- A message object MIMEMultipart needs to constructed with corresponding headers for
From
,To
, andSubject
fields. - Prepare and adding the message body
- Sending the message using SMTP Object
Let’s perform each of these steps here.
3. Defining Connection Details
To define the SMTO Server connection details, we will make a main() function in which we define our HostLet’s look at a code snippet:
1 2 3 4 5 6 7 8 9 |
def main(): names, emails = get_users('contacts.txt') # read user details message_template = parse_template('message.txt') # set up the SMTP server smtp_server = smtplib.SMTP(host="host_address_here", port=port_here) smtp_server.starttls() smtp_server.login(FROM_EMAIL, MY_PASSWORD) |
In above main() function, we first received the user names and emails followed by which we constructed the SMTP Server Object. The host
and port
depends on the service provider you use to send emails. For example, in case of Gmail, we will have:
1 2 3 |
smtp_server = smtplib.SMTP(host="smtp.gmail.com", port=25) |
Now, we’re finally ready to send the email.
4. Sending the email from Python Program
Here is a sample program:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# Get each user detail and send the email: for name, email in zip(names, emails): multipart_msg = MIMEMultipart() # create a message # substitute user name with template String message = message_template.substitute(USER_NAME=name.title()) # message parameter definition multipart_msg['From']=FROM_EMAIL multipart_msg['To']=email multipart_msg['Subject']="JournalDev Subject" # add in the message body multipart_msg.attach(MIMEText(message, 'plain')) # send the message via the server smtp_server.send_message(multipart_msg) del multipart_msg # Terminate the SMTP session and close the connection smtp_server.quit() if __name__ == '__main__': main() |
We can now see the email arriving at the addresses we defined in the file. To close up, let’s look at the complete code we used for sending emails:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
import smtplib from string import Template from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText FROM_EMAIL = 'email' MY_PASSWORD = 'mypassword' def get_users(file_name): names = [] emails = [] with open(file_name, mode="r", encoding='utf-8') as user_file: for user_info in user_file: names.append(user_info.split()[0]) emails.append(user_info.split()[1]) return names, emails def parse_template(file_name): with open(file_name, 'r', encoding='utf-8') as msg_template: msg_template_content = msg_template.read() return Template(msg_template_content) def main(): names, emails = get_users('contacts.txt') # read user details message_template = parse_template('message.txt') # set up the SMTP server smtp_server = smtplib.SMTP(host="host-here", port=port-here) smtp_server.starttls() smtp_server.login(FROM_EMAIL, MY_PASSWORD) # Get each user detail and send the email: for name, email in zip(names, emails): multipart_msg = MIMEMultipart() # create a message # add in the actual person name to the message template message = message_template.substitute(USER_NAME=name.title()) # Prints out the message body for our sake print(message) # setup the parameters of the message multipart_msg['From']=FROM_EMAIL multipart_msg['To']=email multipart_msg['Subject']="JournalDev Subject" # add in the message body multipart_msg.attach(MIMEText(message, 'plain')) # send the message via the server set up earlier. smtp_server.send_message(multipart_msg) del multipart_msg # Terminate the SMTP session and close the connection smtp_server.quit() if __name__ == '__main__': main() |
Note that you will have to replace the host and port property for the email provider you use. For Gmail, I made use of these properties:
1 2 3 |
smtp_server = smtplib.SMTP(host="smtp.gmail.com", port=587) |
When we run this script, we just print the text we send:
Python Sending Emails
Next, in case of Gmail, you might have to turn off the security related to your account. When you configure your email and password and run this script first time, you might receive an email from Gmail like:
Gmail Security Error
Just follow the instructions given in the email and run the script again and you will see that an email has arrived in the email box you configured in the contacts file like:
Email received from Python Script
Reference: Python smtplib Official Docs