Python FastAPI 简介与实战:快速构建 API
在当今快速发展的软件世界中,构建高效、可扩展且易于维护的API是许多应用程序的核心需求。Python生态系统提供了众多Web框架,而FastAPI凭借其卓越的性能、现代化的特性和出色的开发者体验,正迅速成为构建API的首选。
1. 什么是 FastAPI?
FastAPI是一个现代、快速(高性能)的Web框架,用于使用Python 3.7+构建API。它的设计灵感来源于Flask和Starlette(用于Web部分),并利用Pydantic(用于数据验证和序列化)和Type Hints(Python类型提示)的强大功能。
核心优势:
- 极高的性能: 基于Starlette和Uvicorn,性能可与Go和Node.js相媲美。
- 快速开发: 通过类型提示自动生成API文档(OpenAPI/Swagger UI和ReDoc),减少了大量手动编写文档和数据验证代码的工作。
- 代码简洁: 利用Python的类型提示,代码更具可读性和自解释性。
- 强大的数据验证: 基于Pydantic模型,自动进行请求和响应数据验证。
- 依赖注入系统: 简化了复杂逻辑和数据库连接的管理。
- 安全性: 内置了多种安全工具,支持OAuth2等认证方式。
- 异步支持: 原生支持
async/await,轻松处理高并发请求。
2. 环境搭建与安装
在开始之前,确保你已安装Python 3.7或更高版本。推荐使用虚拟环境来管理项目依赖。
“`bash
创建虚拟环境
python -m venv venv
激活虚拟环境 (Windows)
.\venv\Scripts\activate
激活虚拟环境 (macOS/Linux)
source venv/bin/activate
安装FastAPI和Uvicorn (ASGI服务器)
pip install fastapi “uvicorn[standard]”
“`
3. 第一个 FastAPI 应用:Hello World
让我们从一个最简单的“Hello World”API开始。
“`python
main.py
from fastapi import FastAPI
app = FastAPI()
@app.get(“/”)
async def read_root():
return {“message”: “Hello World”}
“`
运行应用:
在终端中,导航到 main.py 文件所在的目录,并运行Uvicorn服务器:
bash
uvicorn main:app --reload
main: 指的是main.py文件。app: 指的是main.py文件中创建的FastAPI()实例。--reload: 当代码发生更改时,自动重新加载服务器(在开发时非常有用)。
现在,打开你的浏览器访问 http://127.0.0.1:8000/,你将看到 {"message": "Hello World"}。
访问 http://127.0.0.1:8000/docs 或 http://127.0.0.1:8000/redoc,你将看到自动生成的交互式API文档。
4. 路径参数 (Path Parameters)
路径参数用于在URL路径中获取变量。
“`python
main.py
from fastapi import FastAPI
app = FastAPI()
@app.get(“/items/{item_id}”)
async def read_item(item_id: int):
return {“item_id”: item_id}
“`
访问 http://127.0.0.1:8000/items/5 将返回 {"item_id": 5}。FastAPI会自动将 item_id 转换为整数类型。
你还可以为路径参数添加类型提示,FastAPI会进行数据校验。如果传入的数据类型不匹配,FastAPI会自动返回一个HTTP 422 Unprocessable Entity错误。
5. 查询参数 (Query Parameters)
查询参数是URL中 ? 后面的键值对,用于过滤、排序等。
“`python
main.py
from fastapi import FastAPI
from typing import Optional
app = FastAPI()
@app.get(“/items/”)
async def read_items(skip: int = 0, limit: Optional[int] = None):
return {“skip”: skip, “limit”: limit}
“`
访问 http://127.0.0.1:8000/items/?skip=10&limit=20 将返回 {"skip": 10, "limit": 20}。
skip: int = 0:skip是一个整数,默认值为0。limit: Optional[int] = None:limit是一个可选的整数,默认值为None。
6. 请求体 (Request Body) 与 Pydantic 模型
对于POST、PUT等请求,客户端通常会发送JSON格式的请求体。FastAPI使用Pydantic模型来定义请求体的结构和数据类型。
首先,定义一个Pydantic模型:
“`python
main.py
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
@app.post(“/items/”)
async def create_item(item: Item):
return item
“`
Item 类继承自 pydantic.BaseModel,定义了预期的JSON数据结构。FastAPI会自动:
- 将请求体解析为JSON。
- 创建
Item模型的一个实例,填充从请求体中获取的数据。 - 对数据进行类型检查。如果数据无效,它将返回一个清晰的错误。
- 将
item对象作为参数传递给你的函数。
你可以通过 http://127.0.0.1:8000/docs 中的Swagger UI来测试这个API。
7. 数据验证和更多 Pydantic 功能
Pydantic提供了丰富的数据验证功能,包括:
- 字段约束:
min_length,max_length,gt(大于),ge(大于等于),lt(小于),le(小于等于) 等。 - 正则表达式: 使用
pydantic.constr或re.Pattern。 - 复杂类型: 支持列表、字典、嵌套模型等。
示例:
“`python
main.py
from fastapi import FastAPI, HTTPException, status
from pydantic import BaseModel, Field
from typing import Optional
app = FastAPI()
class Item(BaseModel):
name: str = Field(…, min_length=3, max_length=50) # 必填,长度限制
description: Optional[str] = Field(None, max_length=300) # 可选,长度限制
price: float = Field(…, gt=0) # 必填,价格必须大于0
tax: Optional[float] = None
@app.post(“/items_validated/”, status_code=status.HTTP_201_CREATED)
async def create_item_validated(item: Item):
return {“message”: “Item created successfully”, “item”: item}
@app.get(“/items_validated/{item_id}”)
async def get_item_validated(item_id: int):
if item_id % 2 != 0:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=”Item not found for odd IDs”
)
return {“item_id”: item_id, “name”: “Even Item”, “price”: 10.0}
“`
在这个例子中,我们使用了 Field 函数来添加更多验证规则。FastAPI会根据这些规则自动进行验证。如果验证失败,它会返回一个详细的错误响应。
我们还展示了如何手动抛出 HTTPException 来返回自定义的错误响应。
8. 依赖注入 (Dependencies)
FastAPI的依赖注入系统是其最强大的功能之一。它允许你声明函数或类作为依赖项,FastAPI会在路径操作函数被调用时自动解析和注入这些依赖项。这有助于实现代码复用、模块化和测试。
示例:公共参数作为依赖
“`python
main.py
from fastapi import FastAPI, Depends, Header
from typing import Optional
app = FastAPI()
async def common_parameters(q: Optional[str] = None, skip: int = 0, limit: int = 100):
return {“q”: q, “skip”: skip, “limit”: limit}
@app.get(“/dependency_items/”)
async def read_items_with_dependency(commons: dict = Depends(common_parameters)):
return commons
另一种使用依赖的方式:直接在路径操作函数中声明
@app.get(“/users/”)
async def read_users(commons: dict = Depends(common_parameters)):
return commons
依赖注入可以用于处理认证、数据库会话等
async def get_token_header(x_token: str = Header(…)):
if x_token != “fake-super-secret-token”:
raise HTTPException(status_code=400, detail=”X-Token header invalid”)
return x_token
@app.get(“/items_secure/”)
async def read_secure_items(token: str = Depends(get_token_header)):
return {“message”: “You have access to secure items!”, “token”: token}
“`
在 read_items_with_dependency 函数中,commons: dict = Depends(common_parameters) 告诉FastAPI在调用 read_items_with_dependency 之前,先调用 common_parameters 函数,并将其返回值注入到 commons 参数中。
9. 总结
FastAPI是一个令人兴奋的现代Python Web框架,它将Python类型提示的优势与高性能结合在一起,为开发者提供了前所未有的开发效率和代码质量。通过本文的介绍和实战,你应该已经对FastAPI的核心概念和用法有了基本的了解。
接下来你可以探索的FastAPI高级特性:
- OAuth2 和 JWT 认证
- 数据库集成 (SQLAlchemy, Tortoise ORM等)
- WebSocket
- 后台任务
- 测试 (FastAPI内置了基于Starlette的TestClient)
- 部署 (结合Docker, Kubernetes等)
无论是构建小型微服务还是大型企业级API,FastAPI都是一个值得投入学习和使用的强大工具。开始你的FastAPI之旅,体验快速、高效、愉悦的API开发吧!