Serving HTML and Static files
FastAPI is not only for APIs; it also provides robust support for serving HTML content and static files, which is essential for web applications that require a frontend. Below, we'll cover how to serve HTML templates and static files like CSS, JavaScript, and images.
Serving HTML Templates
FastAPI uses Jinja2, a fast, secure, and designer-friendly templating engine for Python, to render HTML templates.
Step-by-Step Guide to Serving HTML
- Install Jinja2 and
aiofiles
First, you need to install Jinja2 andaiofiles(an asynchronous file handling library):pip install jinja2 aiofiles - Project Structure
Create a directory structure to hold your templates and static files:fastapi_project/ │ ├── main.py ├── templates/ │ └── index.html ├── static/ │ ├── css/ │ │ └── styles.css │ └── js/ │ └── script.js └── requirements.txt - Setting Up Template Directory
Configure FastAPI to use thetemplatesdirectory for Jinja2 templates.# main.py from fastapi import FastAPI, Request from fastapi.templating import Jinja2Templates from fastapi.staticfiles import StaticFiles app = FastAPI() # Mount the static files directory app.mount("/static", StaticFiles(directory="static"), name="static") # Define the templates directory templates = Jinja2Templates(directory="templates") @app.get("/") async def read_root(request: Request): return templates.TemplateResponse("index.html", {"request": request, "title": "Home"})app.mountis used to serve static files. Thedirectoryparameter points to thestaticfolder, and the files will be accessible under the/staticURL path.Jinja2Templatesis configured to look for templates in thetemplatesdirectory.templates.TemplateResponseis used to renderindex.htmlwith the provided context (liketitle).
- Creating a Basic HTML Template
In thetemplatesdirectory, create anindex.htmlfile:<!-- templates/index.html --> <!DOCTYPE html> <html> <head> <title>{{ title }}</title> <link rel="stylesheet" type="text/css" href="/static/css/styles.css"> </head> <body> <h1>{{ title }}</h1> <p>Welcome to FastAPI with HTML templates!</p> <script src="/static/js/script.js"></script> </body> </html>- This template uses Jinja2 syntax for templating.
- It includes a link to a CSS file and a JavaScript file served from the
staticdirectory.
- Running the Application
Start your FastAPI server:uvicorn main:app --reload
Navigate tohttp://127.0.0.1:8000in your browser to see the rendered HTML.
Serving Static Files
Serving static files is straightforward with FastAPI. You can serve CSS, JavaScript, images, or any other static assets.
Step-by-Step Guide to Serving Static Files
- Mount the Static Directory
As shown above, useapp.mountto serve thestaticdirectory:app.mount("/static", StaticFiles(directory="static"), name="static")- This makes all files in the
staticdirectory accessible under the/staticURL path.
- This makes all files in the
- Accessing Static Files in HTML
Reference static files in your HTML templates using their paths relative to the/staticURL path:<link rel="stylesheet" type="text/css" href="/static/css/styles.css"> <script src="/static/js/script.js"></script>- The above example links a CSS file and a JavaScript file.
- Example Static Files
Create some example static files:/* static/css/styles.css */ body { font-family: Arial, sans-serif; background-color: #f0f0f0; color: #333; } h1 { color: #007bff; }// static/js/script.js console.log("FastAPI with static files!");
These files can be used to style your HTML and add interactivity via JavaScript.
Example Project
Here's a complete example of a FastAPI project that serves HTML and static files:
Project Structure
fastapi_project/
│
├── main.py
├── templates/
│ └── index.html
├── static/
│ ├── css/
│ │ └── styles.css
│ └── js/
│ └── script.js
└── requirements.txt
main.py
from fastapi import FastAPI, Request
from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles
app = FastAPI()
# Mount static files directory
app.mount("/static", StaticFiles(directory="static"), name="static")
# Define the templates directory
templates = Jinja2Templates(directory="templates")
@app.get("/")
async def read_root(request: Request):
return templates.TemplateResponse("index.html", {"request": request, "title": "Home"})
templates/index.html
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
<link rel="stylesheet" type="text/css" href="/static/css/styles.css">
</head>
<body>
<h1>{{ title }}</h1>
<p>Welcome to FastAPI with HTML templates!</p>
<script src="/static/js/script.js"></script>
</body>
</html>
static/css/styles.css
body {
font-family: Arial, sans-serif;
background-color: #f0f0f0;
color: #333;
}
h1 {
color: #007bff;
}
static/js/script.js
console.log("FastAPI with static files!");
Conclusion
By following these steps, you can serve both HTML content and static files using FastAPI. This allows you to build full-featured web applications with a backend API and a frontend served by the same framework.