Getting started with Jinja and FastAPI

A template engine is used to separate presentation logic from data. Through impressions, filters, conditionals, bucles or imports, it allows you to generate the HTML code necessary to represent a web page. The template engine are widely used in server-side programming, since they allow the presentation of data without having to modify the source code.

In short, with a templating engine it is possible to present the data handled by the server, specifically FastApi, and generate the HTML in the process; for example, if we have a list of users, we can print it in a table or similar in HTML using certain functionalities (directives).

About Jinja

Jinja is a template engine written in Python designed to be simple and expressive; Jinja is the templating engine used in other Python web frameworks, such as Flask, it is also very similar to the one used by Django.

With Jinja as a template engine we can easily render API responses.

Jinja's templating engine uses square brackets { } to distinguish its expressions and syntax from HTML:

  1. The {{ }} syntax is called a variable block and we can use it to print in the template.
  2. The {% %} syntax is used to control structures such as if/else, loops, and macros.
  3. The {# #} syntax is for comments.

Using Jinja in FastAPI

In this section, we will see how to install Jinja 2 in a FastAPI project and different examples of how we can use both technologies together to create a web application that will not only process requests on the server and return a response in JSON format, but also also process requests to return HTML pages as responses with which we can manage data.

Install Jinja

To install the template engine known as Jinja, we execute in the project:

$ pip install Jinja2

To use Jinja, we'll create a folder to store the templates: 
templates

And a section for homework: 
templates\task 
And an HTML file: 
templates\task\index.html

With the following content:


<!DOCTYPE html>
<html lang="en">


<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>FastAPI</title>
</head>


<body>
    <h1>Hello world</h1>
</body>
</html>

In the api.py file, we'll create a Jinja2Templates instance object that takes the root folder of the templates as a parameter: 
api.py 
 

from fastapi import Request
from fastapi.templating import Jinja2Templates

templates = Jinja2Templates(directory="templates/")
And we create a function that receives as a parameter the location of the template to be rendered and the user's request:
@app.get('/page')
def index(request: Request):
    return templates.TemplateResponse('task/index.html',{"request": request})

If we access from the browser, we will see:

Hello world

First steps with Jinja

In this section we are going to learn about the main features of Jinja, which range from the use of control blocks to the use of filters and the template in general.

Control blocks

One of the crucial elements in template engines are control blocks; we can perform from conditionals to for loops that work in the same way as in Python; with this it is possible to create conditional logic to render HTML blocks if a condition is met, as well as iterate complete data collections, for example a list of tasks in a table or the like.

Conditionals

We can make use of conditionals to evaluate true and false conditions:

<div>
    {% if True %}
        Is TRUE
    {% endif %}
</div>

Conditionals in Jinja are exactly the same as in Python, we can use else, or, and, etc:

<div>
    {% if True and False %}
        Is True
    {% else %}
        Not is True
    {% endif %}
</div>

Bucle for

Just like the for loop in Python, we can use it in Jinja:

<ul>
{% for item in items %}
    <li>{{ item }}</li>
{% endfor %}
</ul>

In a for loop block, you can access some special variables, the main ones being:

  • loop.index: Gets the current index of the iteration starting from one.
  • loop.index0: Gets the current index of the iteration starting from zero.
  • loop.first: True if this is the first iteration.
  • loop.last: True if it is the last iteration.
  • loop.length: Returns the length of the list.

For example, to use the variable last:

<ul>
    {% for e in [1,2,3,4,5,6,10] %}
    <li>{{ e }} {{ loop.last }} </li>
    {% endfor %}
</ul>

All variables must be used in the for loop.

Filters

Filters in Jinja are one of the most important and versatile features that exist in this template engine; allow you to manipulate the content displayed in a template. There are several predefined filters in Jinja although we can extend the existing ones with custom filters; the filters are applied to the variables that are used, for example, to count the length of a text string, join texts into one, separate by a separator, format dates, numbers and a long etc; in short, they allow for custom manipulations of the content.

To use a filter, use the pipe operator (|) after specifying the argument or arguments, and after the pipe operator, the filter you want to use:

<DATA> | <FILTER>

Let's look at some filters in Jinja.

Filter default

The default filter is used to replace the output if the variable has a null value (not defined):

{{ task | default('This is a default Task') }}

For example, if task is null, we will have an output like:

This is a default Task

If task were defined or we evaluated, for example, a number.

{{ 5 | default('This is a default Task') }}

We would see the number on the screen:

5

This material is part of my complete course and book on FastAPI.

- Andrés Cruz

En español

Andrés Cruz

Develop with Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz In Udemy

I agree to receive announcements of interest about this Blog.