静态文件服务
@app.get("/", include_in_schema=False)
async def root() -> FileResponse:
return FileResponse(os.path.join(STATIC_DIR, "index.html"))
app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")
静态文件是什么?
Web 应用有两类资源:
- 静态文件 :HTML、CSS、JS、图片——内容固定,直接读文件返回
- 动态接口 :API——每次返回不同内容,需要执行代码
app.mount("/static", StaticFiles(directory=STATIC_DIR))
# 效果:访问 http://localhost:8000/static/index.html
# → 返回 static/index.html 文件内容
app.mount 就是把一个 URL 前缀映射到一个目录。
为什么路由要在 mount 之前定义?
FastAPI 按注册顺序匹配路由。 StaticFiles 是个“catch-all”——会匹配 /static/ 下所有路径。如果先 mount 再注册 /api/health ,可能被静态文件拦截。所以 API 路由在前,静态文件在后 。
注意:生产环境不会用 Python 服务静态文件
Python 处理静态文件性能不如专用服务器。生产架构通常是:
用户 → Nginx(静态文件 + 反向代理)→ Uvicorn/FastAPI(只处理 API)
Nginx 用 C 写,直接读文件返回,极快;动态 API 请求才转发给 Python。
Nginx是一个高性能 Web 服务器/反向代理。Nginx 是门口的保安+前台,静态请求自己处理,动态请求转交给后端的 FastAPI。