How to send a simple email using Python

Sending emails can be a tiresome task at times, especially if you have to send the same email to different people with their names included. This blog will go step-by-step into how to simplify this tedious process using python.

The only pre-requisite might be some basic python knowledge. Note: I will be using Python 3 for this blog.

Okay let us start coding already! First step is to create an empty python script and name it however you want, apart from ’email.py’ as this will conflict with the already existing python built-in module email.py.

I shall name my script email_demo.py.

First of all, we need to download the two libraries that we will need for this project.

In [ ]:

# libraries needed
import smtplib
from email.mime.text import MIMEText

Now before getting into the main program, it is good practice to declare the important variables such as your email address or content of the email as global variables outside the main function. This will allow you to make changes easily and to keep the codes tidy. Also, by setting these as global variables, whenever you need to make any changes, you only have to change the value(s) of the global variable(s) and the change(s) will be applied wherever the variable(s) is/are being used inside the main function.

So in our case, the global variables that I am going to declare are:

  1. email address of the sender
  2. password of the sender
  3. subject of the email
  4. content of the email

In [ ]:

email_sender = 'dummy.email.address@email.com'
sender_password = 'duMmy_passWord'
email_subject = "Sending a simple email tutorial!"

Since the content of an email is usually not a one-liner, it is better to use triple quotes for multi-line strings while declaring the email_content variable. Also, I shall leave %s as it is, so as to replace it with the receiver’s name later on.

In [ ]:

email_content = """
Hi %s,

I hope you are having a great day.

If you are trying to learn Python and are reading this blog, I just want to tell you to keep on learning and not to give up.
Python is very useful in many ways. One of the main keys to learn Python is consistency. 

These extra miles that you are taking will pay off eventually.

Many thanks,
Peace
"""

Now let us move into the main function. I will name the function send_email. The input arguments that I will include are send_to which will be the receiver’s email addressname which will be the receiver’s name; and content which will be the contents of the email. Please note that all the arguments will be of the type string or str.

In [ ]:

def send_email(send_to: str, name: str, content: str):

Then we initialise the message using MIMEText() and then fill in the header fields (“To”, “From”, …) with the global variables that have been declared earlier. Please note that MIMEText() takes 1 argument, which in our case will be (content % name), that is the content of the email with the name of the receiver fed in. I’ll show you how to extract the name later in the blog.

When this has been done, python must be told to send the message as a string using the as_string method.

In [ ]:

 def send_email(send_to: str, name: str, content: str):
   message = MIMEText(content % name)

   message['From'] = f'Human Being!<{email_sender}>'
   message['To'] = send_to
   message['Subject'] = email_subject

   text = message.as_string()

I know some of you might be wondering why I have put message['From'] = f'Human Being!<{email_sender}>' instead of just message['From'] = email_sender. Well to keep it short, this is just for aesthetic purposes. Please refer to below images to see how it appears on the receiver’s side when using message['From'] = email_sender compared to message['From'] = f'Human Being!<{email_sender}>' respectively.

Yosh! So the function has been declared, the message has been initialised and the content of the email has been attached. What’s next now?! Oh, we need to actually send it!

Since I am using gmail, the server address will be smtp.gmail.com and the port number will be 587 as I am using TLS (server.starttls()). For the login details, the global variables email_sender and sender_password that I have declared earlier are used. For the “who sent what to whom” in server.sendmail(), the global variables are used again. And I make sure that I quit() the server.

In [ ]:

 def send_email(send_to: str, name: str, content: str):
    message = MIMEText(content % name)

    message['From'] = f'Human Being!<{email_sender}>'
    message['To'] = send_to
    message['Subject'] = email_subject

    text = message.as_string()

    server = smtplib.SMTP('smtp.gmail.com', 587)
    server.starttls()
    server.login(email_sender, sender_password)

    server.sendmail(email_sender, send_to, text)
    server.quit()

Yay! We are finally done! Or are we? There is one last thing I need to do to get the most out of it.

Suppose we have a python dictionary consisting of the full names and email addresses of the people we want to send a particular email (internal colleagues for example). Using the dictionary, we can get the name and email address of the receiver.

In [ ]:

internal_colleagues_dict = {'Joshua Bond': 'josh.bond@xyz.co.uk', 'Lionel Stones': 'lionel.stones@xyz.co.uk', 'Ashley Brown': 'ashley.brown@xyz.co.uk'}

All we need to do is extract the first name from the name using the .split()[0] method. If we want the last name, we must use .split()[-1] instead. One way to do it in one go is to wrap it all in a for loop.

Note: Do not forget about the content argument.

In [ ]:

for contact in internal_colleagues_dict:
    first_name = contact.split()[0]
    # last_name = contact.split()[-1]
    receiver_email = internal_colleagues_dict[contact]
    
    send_email(receiver_email, first_name, email_content)

And off we g.. Oops! SMTPAuthenticationError!!

Note about SMTPAuthenticationError: 

In a nutshell, Google is not allowing you to log in via smtplib because it has flagged this login attempt by python as “less secure”. To overcome this issue, you can click on the link below, log in your google account if you have not already, and allow access. Now if you try to run the program again, it should run without any problem.

https://www.google.com/settings/security/lesssecureapps

The full code is shown below:

In [ ]:

# libraries needed
import smtplib
from email.mime.text import MIMEText

# Please note that all the names and email addresses used are anonymous.
internal_colleagues_dict = {'Joshua Bond': 'josh.bond@xyz.co.uk', 'Lionel Stones': 'lionel.stones@xyz.co.uk', 'Ashley Brown': 'ashley.brown@xyz.co.uk'}

# global variables
email_sender = 'dummy.email.address@email.com'
sender_password = 'duMmy_passWord'
email_subject = "Sending a simple email tutorial!"

email_content = """
Hi %s,

I hope you are having a great day.

If you are trying to learn Python and are reading this blog, I just want to tell you to keep on learning and not to give up.
Python is very useful in many ways. One of the main keys to learn Python is consistency. 

These extra miles that you are taking will pay off eventually.

Many thanks,
Peace
"""


# main function
def send_email(send_to: str, name: str, content: str):
    message = MIMEText(content % name)

    message['From'] = f'Human Being!<{email_sender}>'
    message['To'] = send_to
    message['Subject'] = email_subject

    text = message.as_string()

    server = smtplib.SMTP('smtp.gmail.com', 587)
    server.starttls()
    server.login(email_sender, sender_password)

    server.sendmail(email_sender, send_to, text)
    server.quit()


# running the code
for contact in internal_colleagues_dict:
    first_name = contact.split()[0]
    # last_name = contact.split()[-1]
    receiver_email = internal_colleagues_dict[contact]
    
    send_email(receiver_email, first_name, email_content)

By changing the email_subjectemail_content and the contacts dictionary, we can send different emails to different people using the same function. A brief example is shown below.

Note: I have included subject as a fourth argument of type str so that the codes can be used in a more generalised manner. In this way, you can send different emails to different groups just by running the codes once.

In [ ]:

# libraries needed
import smtplib
from email.mime.text import MIMEText

# Please note that all the names and email addresses used are anonymous.
marketing_dict = {'Estas Cortez': 'estas.cortez@gmail.com', 'Pravin Junior': 'pra.junior@email.co.uk', 'Chloe Sandstorm': 'chloe.003@email.ac.uk'}

internal_colleagues_dict = {'Joshua Bond': 'josh.bond@xyz.co.uk', 'Lionel Stones': 'lionel.stones@xyz.co.uk', 'Ashley Brown': 'ashley.brown@xyz.co.uk'}

# global variables
email_sender = 'dummy.email.address@email.com'
sender_password = 'duMmy_passWord'

email_subject_marketing = "New product!"
email_subject_colleagues = "Meeting update!"

email_content_marketing = """
Hi %s,

I hope you are having a great day.

If you are trying to learn Python and are reading this blog, I just want to tell you to keep on learning and not to give up.
Python is very useful in many ways. One of the main keys to learn Python is consistency. 

These extra miles that you are taking will pay off eventually.

Many thanks,
XYZ Team
"""

email_content_colleagues = """
Hi %s,

I hope you are having a great day.

Please note that the tomorrow's meeting will take place at 13:00 on MS Teams. 

Looking forward to see you.

Many thanks,
P
"""


# main function
def send_email(send_to: str, name: str, content: str, subject: str):
    message = MIMEText(content % name)

    message['From'] = f'Human Being!<{email_sender}>'
    message['To'] = send_to
    message['Subject'] = email_subject

    text = message.as_string()

    server = smtplib.SMTP('smtp.gmail.com', 587)
    server.starttls()
    server.login(email_sender, sender_password)

    server.sendmail(email_sender, send_to, text)
    server.quit()


# running the code for internal colleagues
for contact in internal_colleagues_dict:
    first_name = contact.split()[0]
    # last_name = contact.split()[-1]
    receiver_email = internal_colleagues_dict[contact]
    
    send_email(receiver_email, first_name, email_content_colleagues, email_subject_colleagues)

# running the code for marketing
for contact in marketing_dict:
    first_name = contact.split()[0]
    # last_name = contact.split()[-1]
    receiver_email = marketing_dict[contact]
    
    send_email(receiver_email, first_name, email_content_marketing, email_subject_marketing)

Thank you for taking your time to read the blog. I hope this has been useful to you.

By Parwez Diloo
Published
Categorized as blog

Leave a comment

Your email address will not be published. Required fields are marked *