DEV Community

Cover image for Send an HTML Email Template with Python and Jinja2
Carola Corvalán
Carola Corvalán

Posted on

Send an HTML Email Template with Python and Jinja2

This is my first post in dev.to.
As a beginner developer and as a practice exercise, I have learned how to send an HTML Email template using Python and Jinja2.

In the beginning, I focused on sending simple plain text, images, and template files emails. After understanding the logic of emails, I started to learn about the template engine and how to combine my template file with some data, first with Python's built-in string formatters and then with Jinja2.

In this post I am going to explore:

  • How to set up a local SMTP (Simple Mail Transfer Protocol) and to send an Email with Python.
  • Template engine
  • Loading a template
  • Template Inheritance
  • Control Structures

Set up a local SMTP (Simple Mail Transfer Protocol)

Python contains the built-in smtplib module for sending emails, you can send plain text, images, attachments, and an HTML.

I started installing everything I needed for testing the email functionality.

Import the SMTP

from smtplib import SMTP 
Enter fullscreen mode Exit fullscreen mode

Import from email.mime modules that also Python provides, MIMEtext and MIMEMultipart. MIMEText() objects will contain the HTML, and the MIMEMultipart("alternative") will combine the parts in a single message.

from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
Enter fullscreen mode Exit fullscreen mode

Set up Jinja2

Import from Jinja2 the Environment, FileSystemsLoader, and os. For Jinja2 you can use pip or easy_install.

from jinja2 import Environment, FileSystemLoader
import os
Enter fullscreen mode Exit fullscreen mode

Loading a template with Jinja2.

The FileSystemLoader from Jinja2 helps to get the template from the file system or other location and the Environment will load it.

env = Environment(
    loader=FileSystemLoader('%s/templates/' % os.path.dirname(__file__)))
Enter fullscreen mode Exit fullscreen mode

The data in JSON format

def get_data():
    data = []
    data.append(
        {
         "movies": [
             {         
                 "title": 'Terminator',
                 "description": 'One soldier is sent back to protect her from the killing machine. He must find Sarah before the Terminator can carry out its mission.'
             },
             {                 
                 "title": 'Seven Years in Tibet',
                 "description": 'Seven Years in Tibet is a 1997 American biographical war drama film based on the 1952 book of the same name written by Austrian mountaineer Heinrich Harrer on his experiences in Tibet.'
             },
             {               
                 "title": 'The Lion King',
                 "description": 'A young lion prince is born in Africa, thus making his uncle Scar the second in line to the throne. Scar plots with the hyenas to kill King Mufasa and Prince Simba, thus making himself King. The King is killed and Simba is led to believe by Scar that it was his fault, and so flees the kingdom in shame.'
             }
         ]
         })
    return data
Enter fullscreen mode Exit fullscreen mode

Sending the email with HTML content

After installing all the necessary, I created a method for to send the email, it is include sender, receiver, subject, the HTML and the local server. In this case I used a Gmail account.

def send_mail(bodyContent):
    to_email = 'to@gmail.com'
    from_email = 'from@gmail.com'
    subject = 'This is a email from Python with a movies list!'
    message = MIMEMultipart()
    message['Subject'] = subject
    message['From'] = from_email
    message['To'] = to_email

    message.attach(MIMEText(bodyContent, "html"))
    msgBody = message.as_string()

    server = SMTP('smtp.gmail.com', 587)
    server.starttls()
    server.login(from_email, 'your password')
    server.sendmail(from_email, to_email, msgBody)

    server.quit()
Enter fullscreen mode Exit fullscreen mode

I created a second method to get the data, to load the template from the environment I used before, also I called the get_template() method which will return the loaded Template and for to render the template with the data I called the render() method.

def send_movie_list(event, context):
    json_data = get_data()
    template = env.get_template('child.html')
    output = template.render(data=jsonData[0])
    send_mail(output)    
    return "Mail sent successfully."
Enter fullscreen mode Exit fullscreen mode

Template Engine and Template Inheritance in Jinja2

Jinja2 is a template engine for Python. The template engine allows us to combine a template file with a data model and generate the desired content types.
There are different options when we are working with templates engine, one of them is Python's built-in string formatters, but sometimes we need something more powerful and that is the reason why I chose Jinja2.
Jinja2 is a modern templating language for Python. You can use it within a framework or without it. In this case, I did not use any framework.

Jinja2 contains the template inheritance, it defines an HTML skeleton document. The block tags define one block where the child template can fill in. You can define the number of blocks that you need. In this case, I only have one.
I called this template, "base.html".

<!DOCTYPE html>
<html lang="en">
<head>   
    <title>Movies</title>  
</head>
<body>
    <div id="content">{% block content %}{% endblock %}</div>     
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Control Structures with Jinja2

I created a second template called child, "child.html", contains a for loop to display our movies and a conditional.

{% extends "base.html" %}
{% block content %}
    <h1>Movies</h1>
    <p>
      {% for movie in data['movies'] %} {%if movie['title']!="Terminator" %}
      {{ movie['title'] }}
      {% endif %} {% endfor %}
    </p>
{% endblock %}
Enter fullscreen mode Exit fullscreen mode

It's done!

You can read more about Jinja2 here.

Top comments (5)

Collapse
 
jyunyan profile image
jyun-yan

Hi
i am new to python ,may i know what is "event, context" what should i put in ?

def send_movie_list(event, context):
json_data = get_data()
template = env.get_template('child.html')
output = template.render(data=jsonData[0])
send_mail(output)

return "Mail sent successfully."

Collapse
 
keshavadk profile image
keshavadk

Hi. Can i know what env = Environment(
loader=FileSystemLoader('%s/templates/' % os.path.dirname(file))) means in this script

whether we should change the path if we are using Ubuntu?

Thank you.

Collapse
 
jschilen profile image
jschilen
Collapse
 
david9100 profile image
david9100

Great article - worked like a charm!

Collapse
 
tymg profile image
Matt Green

This was super helpful! Helped me start up my own email project!