作为一名开发者,我相信你一定遇到过这样的场景:1.需要快速开发一个 API,但不想写一堆复杂的样板代码。2.文档和代码总是不同步,维护起来苦不堪言。3.性能要求很高,但又不想学习太复杂的异步编程。4.在 Python 中写 API,总感觉缺少类型安全保障。这些困扰,在我们刚开始接触 Web 开发时都经历过。直到我遇到了 FastAPI------一个现代、高性能的 Python Web 框架,它彻底改变了我对 API 开发的认知。
前言
fastapi,一个用于构建 API 的现代、快速(高性能)的web框架。基于 Python 3.6+ 的类型提示系统,自动生成交互式 API 文档,性能接近 Node.js 和 Go,学习曲线却非常平缓。更重要的是,它完美地解决了上述所有痛点。它出现的比较晚,2018年底才发布在github上。广泛应用于当前各种前后端分离的项目开发,测试运维自动化以及微服务的场景中。
在这篇教程中,我将带你从零开始,一步步构建一个完整的 FastAPI 项目,包含 API 接口开发和 HTML 页面渲染(使用 Jinja2 模板引擎)。通过这个项目,你将掌握 FastAPI 的核心用法,并理解为什么它是当前 Python API 开发的最佳选择之一。

一、FastAPI 核心优势
在开始代码实现之前,让我先分享一下 FastAPI 最吸引我的几个特性:
1. 极速性能
FastAPI 基于 Starlette(异步 Web 框架)和 Pydantic(数据验证库),性能可以与 Node.js 和 Go 并肩。官方测试显示,它的性能是 Flask 的 10-100 倍。
2. 自动文档生成
编写代码时,FastAPI 会自动根据类型提示生成交互式 API 文档。你不需要单独维护文档,代码就是文档------这完全解决了文档同步问题。
3. 类型安全
通过 Python 类型提示,FastAPI 自动验证请求和响应数据,减少了 40% 的人为错误。你再也不用写一堆 if 语句来验证用户输入了。
4. 异步支持
原生支持 async/await 语法,处理数据库操作、HTTP 请求等异步任务时非常简单,性能也更好。
5. 生产就绪
FastAPI 不是玩具框架------它已经在 Uber、Netflix、Microsoft 等大公司的生产环境中得到了验证。
二、环境准备
环境配置往往是新手学习新技术时的第一个障碍。我刚开始学 FastAPI 时,也踩了不少坑。下面是我总结的最简单、最可靠的配置方法。
2.1 Python 版本检查
首先,确保你的 Python 版本是 3.6 或更高。打开终端(Windows 用 CMD 或 PowerShell,Mac/Linux 用 Terminal),输入:
bash
python --version
# 或
python3 --version
技巧提示:我强烈建议使用 Python 3.7+,因为 FastAPI 的一些高级特性(如数据类)在 3.7 中更完善。
2.2 创建虚拟环境
为什么需要虚拟环境?想象一下:你同时在做两个项目,一个用 FastAPI 0.68,另一个用 0.95。如果没有虚拟环境,这两个版本的包会冲突,导致各种奇怪的问题。
bash
# 使用 venv(Python 3.3+ 自带)
python -m venv fastapi-env
# 激活虚拟环境
# Windows
fastapi-env\Scripts\activate
# Mac/Linux
source fastapi-env/bin/activate
激活后,你的命令行提示符前会出现 (fastapi-env),表示已经在虚拟环境中了。
2.3 安装依赖
在虚拟环境中,安装必要的包:
bash
pip install fastapi uvicorn jinja2
验证安装是否成功:
bash
python -c "import fastapi; print(f'FastAPI 版本: {fastapi.__version__}')"
三、第一个 FastAPI 应用:Hello World
环境准备好了,让我们写第一个 API。我建议你跟着我一步步来,不要复制粘贴,亲手敲代码感受一下。
3.1 项目结构
创建一个新文件夹 fastapi-demo,然后在里面创建以下结构:
fastapi-demo/
├── main.py # 主应用文件
└── templates/ # 模板文件夹
├── index.html # 首页模板
├── item_detail.html # 商品详情页模板
├── base.html # 基础布局模板
└── error.html # 错误页面模板
3.2 编写基础代码
打开 main.py,输入以下代码:
python
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
app = FastAPI(title="产品展示系统", description="一个基于 FastAPI 的简单电商演示")
# 配置 Jinja2 模板引擎
templates = Jinja2Templates(directory="templates")
# 示例数据
ITEMS = [
{"id": 1, "name": "无人机", "price": 2999},
{"id": 2, "name": "智能手表", "price": 1599}
]
@app.get("/", response_class=HTMLResponse, name="首页")
async def read_root(request: Request):
"""根路径的 GET 请求处理函数,返回产品列表页面"""
return templates.TemplateResponse("index.html", {"request": request, "items": ITEMS})
@app.get("/items/{item_id}", response_class=HTMLResponse, name="商品详情")
async def read_item(request: Request, item_id: int):
"""
带路径参数的示例
参数:
- item_id: 路径参数,自动转换为 int 类型
"""
item = next((i for i in ITEMS if i["id"] == item_id), None)
if not item:
return templates.TemplateResponse("error.html", {"request": request, "error": "商品不存在"})
return templates.TemplateResponse("item_detail.html", {"request": request, "item": item})
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8000, reload=True)
3.3 创建模板文件
在 templates 文件夹中创建以下模板文件:
base.html(基础布局)
html
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}产品展示系统{% endblock %}</title>
<style>
body {
font-family: "Microsoft YaHei", Arial;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.item {
border: 1px solid #ddd;
padding: 15px;
margin: 10px 0;
border-radius: 8px;
}
.item:hover {
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.price { color: #e74c3c; font-weight: bold; }
.discount { color: #27ae60; font-size: 0.9em; }
header h1 { color: #3498db; border-bottom: 2px solid #3498db; padding-bottom: 10px; }
footer { margin-top: 40px; text-align: center; color: #999; font-size: 0.9em; }
</style>
</head>
<body>
<header>
<h1>产品展示系统</h1>
</header>
<main>{% block content %}{% endblock %}</main>
<footer>© 2024 FastAPI 商城</footer>
</body>
</html>
index.html(首页)
html
{% extends "base.html" %}
{% block title %}产品列表{% endblock %}
{% block content %}
<h2>所有商品</h2>
<div class="items">
{% for item in items %}
<div class="item">
<h3>{{ item.name }}</h3>
<p class="price">价格: ¥{{ item.price }}</p>
<a href="/items/{{ item.id }}">查看详情</a>
</div>
{% endfor %}
</div>
{% endblock %}
item_detail.html(商品详情页)
html
{% extends "base.html" %}
{% block title %}{{ item.name }} 详情{% endblock %}
{% block content %}
<div class="item-detail">
<h2>{{ item.name }}</h2>
<p class="price">价格: ¥{{ item.price }}</p>
<p>产品ID: {{ item.id }}</p>
{% if item.price > 2000 %}
<p class="discount">🔥 高端产品</p>
{% endif %}
</div>
{% endblock %}
error.html(错误页面)
html
{% extends "base.html" %}
{% block title %}错误{% endblock %}
{% block content %}
<h2>错误信息</h2>
<p>{{ error }}</p>
{% endblock %}
3.4 启动项目
现在,你可以直接运行 main.py 文件来启动项目:
bash
python main.py
解释:
uvicorn.run(app, host="127.0.0.1", port=8000, reload=True):启动 FastAPI 应用reload=True:开发模式,代码修改后自动重启服务器
四、项目测试与文档查看
启动服务后,访问以下 URL 进行测试:
4.1 访问页面
4.2 查看自动生成的 API 文档
FastAPI 自动生成了两种格式的 API 文档:
-
交互式 API 文档 (Swagger UI):
- 访问 http://127.0.0.1:8000/docs
- 你可以在这里直接测试 API 接口
-
ReDoc 文档:
- 访问 http://127.0.0.1:8000/redoc
- 提供更简洁、更专业的文档视图
五、理解关键概念
现在,让我们深入理解 FastAPI 中的几个关键概念。
5.1 路由与路径参数
python
@app.get("/items/{item_id}")
async def read_item(request: Request, item_id: int):
...
/items/{item_id}:路由定义,{item_id}是路径参数item_id: int:路径参数类型注解,FastAPI 会自动验证类型- 如果访问
/items/abc这样的路径,FastAPI 会自动返回 422 错误
5.2 模板引擎与上下文传递
python
return templates.TemplateResponse("index.html", {"request": request, "items": ITEMS})
request:必须包含的参数,因为 Jinja2 模板需要它items:传递给模板的数据,在模板中可以通过{``{ items }}访问
5.3 响应类型注解
python
@app.get("/", response_class=HTMLResponse)
response_class=HTMLResponse:指定返回类型为 HTML- 这样,FastAPI 会自动设置正确的 Content-Type 响应头
六、生产环境部署建议
当你的代码准备好部署到生产环境时,有以下几点建议:
6.1 使用多进程运行
bash
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4
--workers 4:根据 CPU 核心数设置工作进程数,一般是核心数的 2-4 倍
6.2 使用 Gunicorn 管理进程
bash
pip install gunicorn
gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app
6.3 使用 Nginx 反向代理
nginx
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
七、项目扩展思路
现在你已经有了一个基础的项目,下面是一些扩展思路,可以让你的项目更加强大:
7.1 添加表单处理
python
from fastapi import Form
@app.post("/items/create")
async def create_item(
name: str = Form(...),
price: float = Form(...)
):
new_id = max(i["id"] for i in ITEMS) + 1
ITEMS.append({"id": new_id, "name": name, "price": price})
return {"message": "商品创建成功"}
7.2 添加静态文件服务
python
from fastapi.staticfiles import StaticFiles
app.mount("/static", StaticFiles(directory="static"), name="static")
7.3 添加数据库连接
可以使用 SQLAlchemy 或 Tortoise ORM 与数据库交互。
7.4 添加身份验证
可以使用 OAuth2 或 JWT 进行身份验证。
八、学习资源推荐
官方文档
示例项目
视频教程
总结
通过本教程,详细你已经从零开始搭建了一个完整的 FastAPI 项目,并使用 Jinja2 模板引擎生成了美观的 HTML 页面。并学会了如何使用自动生成的 API 文档来调试和测试。
FastAPI 的强大之处在于它的简单性和高性能。你只需要专注于业务逻辑,剩下的事情 FastAPI 都会帮你处理。强烈建议你在实际项目中尝试使用 FastAPI,相信它会给你带来全新的开发体验。如果你在学习过程中遇到任何问题,或者有任何建议,欢迎在评论区与我交流!
项目资源: