Table of Contents
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.