- Spec files
pypi-fastapi
Describes: pkg:pypi/fastapi@0.116.x
- Description
- FastAPI framework, high performance, easy to learn, fast to code, ready for production
- Author
- tessl
- Last updated
static-templating.md docs/
1# Static Files and Templating23FastAPI provides built-in support for serving static files and rendering HTML templates, enabling the creation of full web applications that combine API endpoints with frontend content. This functionality is essential for applications that need to serve HTML pages, CSS, JavaScript, images, and other static assets alongside their API functionality.45## Capabilities67### Static Files Serving89Class for serving static files such as HTML, CSS, JavaScript, images, and other assets from the filesystem.1011```python { .api }12class StaticFiles:13def __init__(14self,15*,16directory: str = None,17packages: List[str] = None,18html: bool = False,19check_dir: bool = True,20follow_symlink: bool = False,21) -> None:22"""23Create static files application for serving static content.2425Parameters:26- directory: Directory path containing static files27- packages: List of Python packages containing static files28- html: Whether to serve HTML files for directory requests29- check_dir: Whether to check if directory exists on startup30- follow_symlink: Whether to follow symbolic links31"""32```3334### Jinja2 Template Engine3536Template engine integration for rendering dynamic HTML content with data from your API endpoints.3738```python { .api }39class Jinja2Templates:40def __init__(self, directory: str) -> None:41"""42Create Jinja2 templates instance.4344Parameters:45- directory: Directory containing template files46"""4748def TemplateResponse(49self,50name: str,51context: dict,52status_code: int = 200,53headers: dict = None,54media_type: str = None,55background: BackgroundTask = None,56) -> TemplateResponse:57"""58Render template with context data and return as HTTP response.5960Parameters:61- name: Template file name62- context: Dictionary of template variables63- status_code: HTTP status code64- headers: Additional HTTP headers65- media_type: Response content type66- background: Background task to run after response6768Returns:69TemplateResponse with rendered HTML content70"""7172def get_template(self, name: str) -> Template:73"""Get template object by name."""74```7576## Usage Examples7778### Serving Static Files7980```python81from fastapi import FastAPI82from fastapi.staticfiles import StaticFiles8384app = FastAPI()8586# Mount static files directory87app.mount("/static", StaticFiles(directory="static"), name="static")8889# Mount static files with HTML serving90app.mount("/public", StaticFiles(directory="public", html=True), name="public")9192# Serve from Python package93app.mount("/assets", StaticFiles(packages=["mypackage"]), name="assets")94```9596With this setup:97- Files in `./static/` are accessible at `/static/filename.ext`98- Files in `./public/` are accessible at `/public/filename.ext`99- Directory requests to `/public/` will serve `index.html` if `html=True`100- Package assets are served from installed Python packages101102### HTML Template Rendering103104```python105from fastapi import FastAPI, Request106from fastapi.templating import Jinja2Templates107from fastapi.responses import HTMLResponse108109app = FastAPI()110templates = Jinja2Templates(directory="templates")111112@app.get("/", response_class=HTMLResponse)113async def home(request: Request):114return templates.TemplateResponse(115"index.html",116{"request": request, "title": "Home Page"}117)118119@app.get("/user/{user_id}", response_class=HTMLResponse)120async def user_profile(request: Request, user_id: int):121# Simulate user data retrieval122user_data = {"id": user_id, "name": f"User {user_id}"}123return templates.TemplateResponse(124"profile.html",125{126"request": request,127"user": user_data,128"title": f"Profile - {user_data['name']}"129}130)131```132133Template file `templates/index.html`:134135```html136<!DOCTYPE html>137<html>138<head>139<title>{{ title }}</title>140<link rel="stylesheet" href="/static/style.css">141</head>142<body>143<h1>Welcome to FastAPI</h1>144<p>This is a template-rendered page.</p>145<script src="/static/script.js"></script>146</body>147</html>148```149150Template file `templates/profile.html`:151152```html153<!DOCTYPE html>154<html>155<head>156<title>{{ title }}</title>157</head>158<body>159<h1>User Profile</h1>160<p>ID: {{ user.id }}</p>161<p>Name: {{ user.name }}</p>162<a href="/">Back to Home</a>163</body>164</html>165```166167### Complete Web Application Example168169```python170from fastapi import FastAPI, Request, Form171from fastapi.templating import Jinja2Templates172from fastapi.staticfiles import StaticFiles173from fastapi.responses import HTMLResponse, RedirectResponse174from typing import Optional175176app = FastAPI()177178# Mount static files for CSS, JS, images179app.mount("/static", StaticFiles(directory="static"), name="static")180181# Setup templates182templates = Jinja2Templates(directory="templates")183184# In-memory storage for demo185items = []186187@app.get("/", response_class=HTMLResponse)188async def home(request: Request):189return templates.TemplateResponse(190"home.html",191{"request": request, "items": items}192)193194@app.get("/add", response_class=HTMLResponse)195async def add_item_form(request: Request):196return templates.TemplateResponse(197"add_item.html",198{"request": request}199)200201@app.post("/add")202async def add_item(203request: Request,204name: str = Form(...),205description: str = Form(...)206):207item = {"id": len(items) + 1, "name": name, "description": description}208items.append(item)209return RedirectResponse(url="/", status_code=303)210211@app.get("/item/{item_id}", response_class=HTMLResponse)212async def item_detail(request: Request, item_id: int):213item = next((item for item in items if item["id"] == item_id), None)214if not item:215return templates.TemplateResponse(216"404.html",217{"request": request},218status_code=404219)220return templates.TemplateResponse(221"item_detail.html",222{"request": request, "item": item}223)224225# API endpoints for AJAX/SPA integration226@app.get("/api/items")227async def api_get_items():228return {"items": items}229230@app.post("/api/items")231async def api_add_item(item: dict):232new_item = {"id": len(items) + 1, **item}233items.append(new_item)234return new_item235```236237### Template with Custom Filters238239```python240from fastapi import FastAPI, Request241from fastapi.templating import Jinja2Templates242import datetime243244app = FastAPI()245templates = Jinja2Templates(directory="templates")246247# Add custom filter to templates248def format_datetime(value):249return value.strftime("%Y-%m-%d %H:%M:%S")250251templates.env.filters["datetime"] = format_datetime252253@app.get("/dashboard", response_class=HTMLResponse)254async def dashboard(request: Request):255return templates.TemplateResponse(256"dashboard.html",257{258"request": request,259"current_time": datetime.datetime.now(),260"data": {"users": 150, "posts": 1240}261}262)263```264265Template using custom filter:266267```html268<!DOCTYPE html>269<html>270<head>271<title>Dashboard</title>272</head>273<body>274<h1>Dashboard</h1>275<p>Current time: {{ current_time | datetime }}</p>276<p>Users: {{ data.users }}</p>277<p>Posts: {{ data.posts }}</p>278</body>279</html>280```281282### Error Page Templates283284```python285from fastapi import FastAPI, Request, HTTPException286from fastapi.templating import Jinja2Templates287from fastapi.responses import HTMLResponse288289app = FastAPI()290templates = Jinja2Templates(directory="templates")291292@app.exception_handler(404)293async def not_found_handler(request: Request, exc: HTTPException):294return templates.TemplateResponse(295"404.html",296{"request": request},297status_code=404298)299300@app.exception_handler(500)301async def server_error_handler(request: Request, exc: HTTPException):302return templates.TemplateResponse(303"500.html",304{"request": request},305status_code=500306)307```308309## Types310311```python { .api }312from typing import Any, Dict, List, Optional313from starlette.responses import Response314from starlette.background import BackgroundTask315from starlette.templating import _TemplateResponse as TemplateResponse316from jinja2 import Template, Environment317318# Template response type319TemplateResponse = _TemplateResponse320321# Jinja2 environment type322Jinja2Environment = Environment323324# Template context type325TemplateContext = Dict[str, Any]326```