Sling Academy
Home/FastAPI/FastAPI: Render HTML Templates with Dynamic Content

FastAPI: Render HTML Templates with Dynamic Content

Last updated: May 16, 2023

Overview

FastAPI is often used to develop backend APIs. However, you can also use this web framework to render HTML templates and create websites with the help of the HTMLResponse class (can be imported from fastapi.responses) and the Jinja2Templates class (can be imported from fastapi.templating). You can see a live demo in the URL below:

https://api.slingacademy.com/v1/examples/sample-page.html

What you can do is not limited to static HTML files; it’s possible to pass Python variables to your HTML templates to display dynamic content. Let’s explore this in more great detail in this concise and practical article.

The Steps

A template can be a normal HTML file or can be created easily by mixing the standard HTML syntax with Jinja2 syntax like this:

<h1>Hi there</h1>
<p>{{ my_variable }}!</p>

The {{ my_variable }} part is a placeholder for the variable value. When the template is rendered, it will replace it with the actual value of my_variable. The recommended file extension for a template is .html.

In most cases, the process of connecting FastAPI and your HTML templates is:

1. Add a new directory named templates to the root of your project (you can choose another name if you like). This is where you store your HTML templates.

2. Install the jinja2 package:

pip install jinja2

3. Import Jinja2Templates from fastapi.templating:

from fastapi.templating import Jinja2Templates

4. Create a templates object that you can re-use later:

templates = Jinja2Templates(directory="templates")

5. Use the templates you created to render and return a TemplateResponse, passing the request as one of the key-value pairs in the Jinja2 “context”:

@app.get("/some-route", response_class=HTMLResponse)
async def some_route(request: Request):
    my_variable = "Welcome to Sling Academy"
    return templates.TemplateResponse("some-file.html", 
          {
              "request": request, 
               // pass your variables to HTML template here
              "my_variable": my_variable
          }
)

Note that you can pass more variables if you want.

Complete Example

In this example, we will use an HTML template to display a message and the current date time (passed from the Python code).

Screenshot:

Project file structure:

├── main.py
└── templates
    └── home.html

Install jinja2:

pip install jinja2

Add the following to main.py:

# slingacademy.com
# main.py

from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates

from datetime import datetime

app = FastAPI()

templates = Jinja2Templates(directory="templates")


@app.get("/", response_class=HTMLResponse)
async def home(request: Request):
    message = "Welcome to Sling Academy"

    # get and format current local date and time
    now = datetime.now() 
    current_time = now.strftime("%Y-%m-%d %H:%M:%S") 

    return templates.TemplateResponse(
        "home.html",
        {
            "request": request,
            "message": message,
            "current_time": current_time
        }
)

Then add this to templates/home.html:

<!-- templates/home.html -->
<html>

<head>
    <title>Home Page - Sling Academy</title>
</head>

<body style="padding: 30px">
    <!-- Display variables passed from Python code -->
    <h1>{{ message }}</h1>
    <h3>The current time is: {{ current_time }}</h3>
</body>

</html>

Start your app by running uvicorn main:app --reload then go to http://localhost:8000/ to check the result.

Next Article: How to Run Background Tasks in FastAPI (2 Ways)

Previous Article: How to Return PDF Files in FastAPI (3 Examples)

Series: FastAPI Request & Response Tutorials

FastAPI

You May Also Like

  • Popular useful built-in Jinja filters you should know
  • How to remove consecutive whitespace in rendered Jinja pages
  • How to format large numbers with thousand separators in Jinja template
  • How to format date time in Jinja templates
  • FastAPI + Jinja: How to create custom filters
  • How to pass variables from Python (FastAPI) to Jinja
  • How to decode Jinja response to string
  • How to create and use macros in Jinja
  • How to use namespace in Jinja
  • How to use if/ else in Jinja
  • How to use loops in Jinja
  • FastAPI + SQLAlchemy: Using cursor-based pagination
  • FastAPI: How to use macros in Jinja templates
  • Fixing Common Swagger UI Errors in FastAPI
  • FastAPI Error: 307 Temporary Redirect – Causes and Solutions
  • FastAPI Error: Expected UploadFile, received ‘str’
  • Resolving FastAPI ImportError: No Known Parent Package
  • FastAPI Error: No module named ‘pydantic_core._pydantic_core’
  • Resolving FastAPI 422 Error: Value is not a valid dict