FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,基于标准 Python 类型提示。它允许开发者快速构建、测试和部署 RESTful API 服务,同时提供自动化的交互式 API 文档。
路由定义:通过装饰器如 @app.get()
、@app.post()
等定义不同的 HTTP 方法对应的路由处理函数。
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def read_root():
return {"message": "Hello World"}
参数解析:自动解析路径参数、查询参数、请求体等,支持复杂数据类型的验证和转换。
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}
依赖注入:通过 Depends
实现依赖项的注入,简化代码复用和模块化设计。
from fastapi import Depends, FastAPI
async def common_parameters(q: str = None, skip: int = 0, limit: int = 100):
return {"q": q, "skip": skip, "limit": limit}
app = FastAPI()
@app.get("/items/")
async def read_items(commons: dict = Depends(common_parameters)):
return {"items": [{"item_id": "Foo"}], **commons}
中间件支持:可以添加中间件来处理跨域请求、请求日志记录等全局功能。
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
自动文档生成:内置了交互式的 API 文档,如 Swagger UI 和 ReDoc,方便开发者和调用者查看和测试 API。
http://localhost:8000/docs
或 http://localhost:8000/redoc
即可查看自动生成的文档。自定义异常处理:可以定义自定义的异常处理器来处理特定的异常情况,返回统一的错误响应格式。
from fastapi import FastAPI, HTTPException, status
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
app = FastAPI()
@app.exception_handler(HTTPException)
async def http_exception_handler(request, exc):
return JSONResponse(
status_code=exc.status_code,
content={"detail": exc.detail},
)
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc):
return JSONResponse(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
content={"detail": "Validation error"},
)
异步支持:充分利用 Python 的异步特性,提高并发处理能力,适合处理 I/O 密集型任务。
import asyncio
from fastapi import FastAPI
app = FastAPI()
async def simulate_db_call():
await asyncio.sleep(1)
return {"data": "result"}
@app.get("/async-items/")
async def get_async_items():
data = await simulate_db_call()
return data
数据校验与转换:结合 Pydantic 模型,对请求体进行严格的校验和数据类型转换,确保数据的完整性和正确性。
from pydantic import BaseModel
from fastapi import FastAPI, status
app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
@app.post("/items/", status_code=status.HTTP_201_CREATED)
async def create_item(item: Item):
return item.dict()
支持 WebSocket:除了传统的 HTTP 请求,还支持 WebSocket 实时通信,适用于需要双向通信的场景,如聊天应用、实时数据推送等。
from fastapi import FastAPI, WebSocket
app = FastAPI()
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
await websocket.send_text(f"Message text was: {data}")
插件生态系统:丰富的第三方插件支持,如数据库集成、认证授权、缓存等,可以快速扩展应用的功能。
fastapi-jwt-auth
插件实现 JWT 认证from fastapi import FastAPI, Depends, HTTPException
from fastapi_jwt_auth import AuthJWT
from pydantic import BaseModel
app = FastAPI()
class Settings(BaseModel):
authjwt_secret_key: str = "secret-key"
@AuthJWT.load_config
def get_config():
return Settings()
@app.post("/login")
async def login(user: dict, Authorize: AuthJWT = Depends()):
if user.username != "test" or user.password != "test":
raise HTTPException(status_code=401, detail="Bad username or password")
access_token = Authorize.create_access_token(subject=user.username)
return {"access_token": access_token}
@app.get("/protected")
async def protected(Authorize: AuthJWT = Depends()):
Authorize.jwt_required()
current_user = Authorize.get_jwt_subject()
return {"user": current_user}
BackgroundTasks 用于在处理 HTTP 请求或 WebSocket 连接时,执行一些耗时的后台任务,而不需要让客户端等待这些任务完成。这在发送邮件、处理日志、清理数据等场景中非常有用。
添加后台任务:通过将函数作为参数传递给 BackgroundTasks
,在请求处理完成后自动执行。
from fastapi import BackgroundTasks, FastAPI
app = FastAPI()
def write_log(message: str):
with open("log.txt", mode="a") as log_file:
log_file.write(message + "\n")
@app.post("/send-notification/")
async def send_notification(email: str, background_tasks: BackgroundTasks):
background_tasks.add_task(write_log, f"Notification sent to {email}")
return {"message": "Notification sent in the background"}
传递参数给后台任务:可以向后台任务函数传递多个参数,包括从请求中获取的数据。
def process_data(data: dict, user_id: int):
# 处理数据并保存到数据库等操作
pass
@app.post("/process-data/")
async def process_data_endpoint(data: dict, background_tasks: BackgroundTasks):
user_id = 123 # 假设从请求中获取用户 ID
background_tasks.add_task(process_data, data, user_id)
return {"message": "Data processing started"}
后台任务的依赖注入:后台任务也可以使用依赖注入来获取所需的数据或服务。
from fastapi import Depends
async def get_db():
db = DBConnection()
try:
yield db
finally:
db.close()
def update_database(db: DBConnection, item_id: int):
# 更新数据库操作
pass
@app.put("/items/{item_id}")
async def update_item(
item_id: int,
background_tasks: BackgroundTasks,
db: DBConnection = Depends(get_db),
):
background_tasks.add_task(update_database, db, item_id)
return {"message": "Item update started"}
后台任务的异常处理:可以为后台任务定义异常处理逻辑,捕获任务执行过程中可能出现的错误。
def error_handler(func):
def wrapper(*args, **kwargs):
try:
func(*args, **kwargs)
except Exception as e:
# 记录错误日志等操作
print(f"Error occurred: {e}")
return wrapper
@error_handler
def risky_task():
# 可能会出错的任务
pass
@app.post("/run-risky-task/")
async def run_risky_task(background_tasks: BackgroundTasks):
background_tasks.add_task(risky_task)
return {"message": "Risky task started"}
后台任务的状态监控:通过一些机制(如数据库记录、消息队列等)监控后台任务的执行状态,以便后续查询或处理。
from datetime import datetime
def record_task_status(task_id: str, status: str):
# 将任务状态记录到数据库或其他存储中
pass
def long_running_task(task_id: str):
record_task_status(task_id, "started")
# 执行长时间任务
record_task_status(task_id, "completed")
@app.post("/start-task/")
async def start_task(background_tasks: BackgroundTasks):
task_id = str(uuid.uuid4())
background_tasks.add_task(long_running_task, task_id)
record_task_status(task_id, "pending")
return {"task_id": task_id, "message": "Task started"}
后台任务的优先级控制:根据任务的重要性和紧急程度,设置不同的优先级,确保高优先级任务优先执行。
class PriorityBackgroundTasks:
def __init__(self):
self.tasks = []
def add_task(self, func, *args, priority=0, **kwargs):
self.tasks.append((priority, func, args, kwargs))
self.tasks.sort(key=lambda x: x[0]) # 按优先级排序
async def run(self):
while self.tasks:
priority, func, args, kwargs = self.tasks.pop(0)
await func(*args, **kwargs)
priority_background_tasks = PriorityBackgroundTasks()
async def high_priority_task():
# 高优先级任务
pass
async def low_priority_task():
# 低优先级任务
pass
@app.post("/run-priority-tasks/")
async def run_priority_tasks():
priority_background_tasks.add_task(high_priority_task, priority=1)
priority_background_tasks.add_task(low_priority_task, priority=2)
await priority_background_tasks.run()
return {"message": "Tasks started with priority"}
后台任务的分布式执行:在多服务器或容器环境下,将后台任务分布到不同的工作进程或机器上执行,提高任务处理的并发能力和可靠性。
from celery import Celery
celery_app = Celery('tasks', broker='pyamqp://guest@localhost//')
@celery_app.task
def distributed_task():
# 分布式执行的任务
pass
@app.post("/start-distributed-task/")
async def start_distributed_task():
distributed_task.delay()
return {"message": "Distributed task started"}
后台任务的进度跟踪与反馈:对于长时间运行的任务,向客户端提供任务进度的实时反馈,增强用户体验。
from fastapi import WebSocket
class TaskProgress:
def __init__(self):
self.progress = 0
self.websocket: WebSocket = None
async def update_progress(self, progress: int):
self.progress = progress
if self.websocket:
await self.websocket.send_text(f"Progress: {progress}%")
async def run_task(self):
for i in range(0, 101, 10):
await self.update_progress(i)
await asyncio.sleep(1)
task_progress = TaskProgress()
@app.websocket("/ws/progress")
async def websocket_progress(websocket: WebSocket):
await websocket.accept()
task_progress.websocket = websocket
await task_progress.run_task()
await websocket.close()
@app.get("/start-progress-task/")
async def start_progress_task():
# 启动任务并关联 WebSocket
return {"message": "Progress task started"}
后台任务的资源限制与隔离:对后台任务的资源使用(如内存、CPU、网络带宽等)进行限制和隔离,防止任务之间相互影响,保证系统的稳定性。
import docker
def run_task_in_container():
client = docker.from_env()
container = client.containers.run(
"task-image",
detach=True,
mem_limit="128m",
cpus=0.5
)
container.wait()
container.remove()
@app.post("/run-containerized-task/")
async def run_containerized_task(background_tasks: BackgroundTasks):
background_tasks.add_task(run_task_in_container)
return {"message": "Containerized task started"}
后台任务的调度与计划:根据业务需求,定期或按照特定的时间计划执行后台任务,如定时备份数据、定时发送报告等。
from apscheduler.schedulers.asyncio import AsyncIOScheduler
scheduler = AsyncIOScheduler()
@scheduler.scheduled_job('interval', minutes=1)
async def scheduled_task():
# 每分钟执行一次的任务
pass
scheduler.start()
@app.on_event("startup")
async def startup():
scheduler.start()
@app.on_event("shutdown")
async def shutdown():
scheduler.shutdown()
UploadFile 提供了对文件上传的处理能力,支持单文件和多文件上传,能够获取文件的内容、文件名、内容类型等信息,并方便地将文件保存到服务器或进行进一步的处理。
单文件上传:通过 File
参数接收上传的单个文件,并读取文件内容。
from fastapi import FastAPI, File, UploadFile
app = FastAPI()
@app.post("/upload-file/")
async def create_upload_file(file: UploadFile = File(...)):
contents = await file.read()
# 处理文件内容,如保存到服务器、上传到云存储等
return {"filename": file.filename, "content_type": file.content_type}
多文件上传:允许用户同时上传多个文件,并对每个文件进行处理。
@app.post("/upload-multiple-files/")
async def create_multiple_upload_files(files: list[UploadFile] = File(...)):
for file in files:
contents = await file.read()
# 处理每个文件
return {"filenames": [file.filename for file in files]}
文件保存到服务器:将上传的文件保存到服务器的指定目录。
import shutil
from pathlib import Path
@app.post("/upload-and-save-file/")
async def upload_and_save_file(file: UploadFile = File(...)):
save_dir = Path("uploads")
save_dir.mkdir(exist_ok=True)
save_path = save_dir / file.filename
with open(save_path, "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
return {"filename": file.filename, "save_path": str(save_path)}
文件类型验证:根据文件的扩展名或 MIME 类型,验证上传的文件是否符合要求。
ALLOWED_EXTENSIONS = {"txt", "pdf", "png", "jpg", "jpeg"}
def allowed_file(filename: str):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.post("/upload-validated-file/")
async def upload_validated_file(file: UploadFile = File(...)):
if not allowed_file(file.filename):
raise HTTPException(status_code=400, detail="Invalid file type")
contents = await file.read()
# 处理文件
return {"filename": file.filename}
大文件上传处理:对于大文件上传,可以设置文件大小限制,并采用分块读取的方式处理文件内容,避免内存溢出。
MAX_FILE_SIZE = 10 * 1024 * 1024 # 10MB
@app.post("/upload-large-file/")
async def upload_large_file(file: UploadFile = File(...)):
file_size = 0
while True:
chunk = await file.read(1024 * 1024) # 每次读取 1MB
if not chunk:
break
file_size += len(chunk)
if file_size > MAX_FILE_SIZE:
raise HTTPException(status_code=413, detail="File too large")
# 处理文件块
return {"filename": file.filename, "file_size": file_size}
文件内容流式处理:对于需要实时处理的文件,如视频流、日志流等,采用流式读取和处理的方式,提高效率和响应速度。
from fastapi.responses import StreamingResponse
@app.post("/stream-process-file/")
async def stream_process_file(file: UploadFile = File(...)):
async def process_chunk():
while True:
chunk = await file.read(1024)
if not chunk:
break
# 实时处理文件块,如分析视频帧、解析日志行等
yield chunk
return StreamingResponse(process_chunk(), media_type="application/octet-stream")
文件上传的并发控制:限制同时上传的文件数量,防止服务器资源被过多占用。
from fastapi.concurrency import run_in_threadpool
import asyncio
MAX_CONCURRENT_UPLOADS = 3
semaphore = asyncio.Semaphore(MAX_CONCURRENT_UPLOADS)
async def process_upload(file: UploadFile):
async with semaphore:
contents = await file.read()
# 处理文件
return {"filename": file.filename}
@app.post("/concurrent-upload/")
async def concurrent_upload(files: list[UploadFile] = File(...)):
tasks = [process_upload(file) for file in files]
results = await asyncio.gather(*tasks)
return results
文件上传的断点续传:支持大文件上传的断点续传功能,提高上传的可靠性和用户体验。
from fastapi import Header
@app.post("/resume-upload/")
async def resume_upload(
file: UploadFile = File(...),
range: str = Header(None)
):
if range:
start, end = map(int, range.replace("bytes=", "").split("-"))
file.file.seek(start)
contents = await file.read(end - start + 1)
# 处理文件片段并合并
return {"filename": file.filename, "range": range}
else:
# 普通上传
contents = await file.read()
return {"filename": file.filename}
文件上传的安全增强:对上传的文件进行病毒扫描、内容过滤等安全检查,防止恶意文件上传。
import clamd
cd = clamd.ClamdUnixSocket() # 或使用网络套接字
@app.post("/secure-upload/")
async def secure_upload(file: UploadFile = File(...)):
contents = await file.read()
scan_result = cd.scan_string(contents)
if scan_result and scan_result['stream'][0] == 'OK':
# 文件安全,进行处理
return {"filename": file.filename}
else:
raise HTTPException(status_code=400, detail="Virus detected")
文件上传的元数据处理:提取文件的元数据(如 EXIF 数据、PDF 元数据等),并进行相应的处理或存储。
from PIL import Image
from PIL.ExifTags import TAGS
@app.post("/upload-with-exif/")
async def upload_with_exif(file: UploadFile = File(...)):
contents = await file.read()
image = Image.open(io.BytesIO(contents))
exif_data = image._getexif()
if exif_data:
decoded_exif = {TAGS.get(tag_id): value for tag_id, value in exif_data.items()}
# 处理 EXIF 数据,如记录拍摄时间、地点等
return {"filename": file.filename, "exif_data": decoded_exif}
HTTPException 用于在处理 HTTP 请求时抛出异常,返回特定的 HTTP 状态码和错误信息。WebSocketException 则用于在 WebSocket 连接过程中处理异常情况,如关闭连接、发送错误消息等。
自定义 HTTP 错误响应:在需要返回特定错误信息时,抛出 HTTPException 并指定状态码和详情。
from fastapi import FastAPI, HTTPException
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: int):
if item_id < 0:
raise HTTPException(status_code=400, detail="Item ID must be positive")
return {"item_id": item_id}
WebSocket 异常处理:在 WebSocket 连接建立、接收消息或关闭过程中处理异常,确保连接的正常关闭和错误通知。
from fastapi import WebSocket, WebSocketException
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
try:
await websocket.accept()
while True:
data = await websocket.receive_text()
if data == "error":
raise WebSocketException(code=status.WS_1008_POLICY_VIOLATION, reason="Invalid message")
await websocket.send_text(f"Message: {data}")
except WebSocketException as e:
await websocket.close(code=e.code, reason=e.reason)
全局异常处理器:定义全局的异常处理器,捕获所有未处理的异常并返回统一的错误响应格式。
from fastapi import FastAPI, status
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
app = FastAPI()
@app.exception_handler(HTTPException)
async def http_exception_handler(request, exc):
return JSONResponse(
status_code=exc.status_code,
content={"detail": exc.detail},
)
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc):
return JSONResponse(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
content={"detail": "Validation error"},
)
异常处理的依赖注入:在异常处理过程中使用依赖注入获取所需的服务或数据。
from fastapi import Depends, HTTPException
async def get_db():
db = DBConnection()
try:
yield db
finally:
db.close()
@app.exception_handler(HTTPException)
async def http_exception_handler(request, exc, db: DBConnection = Depends(get_db)):
# 记录错误日志到数据库等操作
return JSONResponse(
status_code=exc.status_code,
content={"detail": exc.detail},
)
异常处理的扩展功能:根据不同的异常类型返回不同的响应格式,如 JSON、XML、HTML 等。
from fastapi import Request
@app.exception_handler(HTTPException)
async def http_exception_handler(request: Request, exc):
accept = request.headers.get("accept", "")
if "application/json" in accept:
return JSONResponse(
status_code=exc.status_code,
content={"detail": exc.detail},
)
elif "text/html" in accept:
return HTMLResponse(
status_code=exc.status_code,
content=f"Error
{exc.status_code}{exc.detail}"
)
else:
return PlainTextResponse(
status_code=exc.status_code,
content=exc.detail
)
异常处理的中间件集成:将异常处理逻辑集成到中间件中,实现更灵活的错误处理和日志记录。
from fastapi import Request, Response
from fastapi.middleware import Middleware
class ExceptionMiddleware:
async def __call__(self, request: Request, call_next):
try:
response = await call_next(request)
return response
except HTTPException as e:
# 自定义错误处理逻辑
return JSONResponse(
status_code=e.status_code,
content={"detail": e.detail},
)
except Exception as e:
# 捕获其他异常并记录日志
return JSONResponse(
status_code=500,
content={"detail": "Internal server error"},
)
app = FastAPI()
app.add_middleware(ExceptionMiddleware)
分布式追踪与异常监控:结合分布式追踪系统和异常监控工具,记录异常发生的上下文信息,便于排查和分析问题。
import sentry_sdk
from sentry_sdk.integrations.asgi import SentryAsgiMiddleware
sentry_sdk.init(
dsn="your_sentry_dsn",
traces_sample_rate=1.0
)
app = FastAPI()
app.add_middleware(SentryAsgiMiddleware)
@app.exception_handler(HTTPException)
async def http_exception_handler(request, exc):
# 记录异常到 Sentry
sentry_sdk.capture_exception(exc)
return JSONResponse(
status_code=exc.status_code,
content={"detail": exc.detail},
)
异常处理的自动化测试:编写自动化测试用例,验证异常处理逻辑的正确性和一致性。
from fastapi.testclient import TestClient
client = TestClient(app)
def test_http_exception():
response = client.get("/items/-1")
assert response.status_code == 400
assert response.json() == {"detail": "Item ID must be positive"}
def test_websocket_exception():
with client.websocket_connect("/ws") as websocket:
websocket.send_text("error")
response = websocket.receive()
assert response["code"] == 1008
assert response["reason"] == "Invalid message"
异常处理的性能优化:对异常处理逻辑进行性能优化,减少不必要的计算和 I/O 操作,提高系统的响应速度。
from fastapi import FastAPI, HTTPException
from fastapi.responses import JSONResponse
error_cache = {}
@app.exception_handler(HTTPException)
async def http_exception_handler(request, exc):
if exc.status_code in error_cache:
return error_cache[exc.status_code]
else:
response = JSONResponse(
status_code=exc.status_code,
content={"detail": exc.detail},
)
error_cache[exc.status_code] = response
return response
多语言异常处理支持:根据客户端的语言偏好返回不同语言的错误信息,提升国际化应用的用户体验。
from fastapi import Request
error_messages = {
400: {
"en": "Bad request",
"zh": "请求错误"
},
404: {
"en": "Not found",
"zh": "未找到"
}
}
@app.exception_handler(HTTPException)
async def http_exception_handler(request: Request, exc):
accept_language = request.headers.get("accept-language", "en")
lang = accept_language.split(",")[0].split(";")[0]
error_message = error_messages.get(exc.status_code, {}).get(lang, "Error")
return JSONResponse(
status_code=exc.status_code,
content={"detail": error_message},
)
这些参数处理函数用于从不同的来源(如请求体、Cookie、查询参数、路径参数等)获取数据,并支持数据验证、依赖注入、安全认证等功能,使参数处理更加灵活和可靠。
Body:处理 JSON 请求体:从请求体中获取 JSON 格式的数据,并自动进行数据验证和转换。
from pydantic import BaseModel
from fastapi import Body, FastAPI
app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
@app.post("/items/")
async def create_item(item: Item = Body(...)):
return item.dict()
Cookie:获取 Cookie 值:从请求的 Cookie 中获取特定的值,支持默认值和数据验证。
from fastapi import Cookie, FastAPI
app = FastAPI()
@app.get("/items/")
async def read_items(ads_id: str = Cookie(None)):
return {"ads_id": ads_id}
Depends:依赖注入:将常见的参数或服务作为依赖项注入到路由处理函数中,减少代码重复。
from fastapi import Depends, FastAPI
async def get_db():
db = DBConnection()
try:
yield db
finally:
db.close()
app = FastAPI()
@app.get("/items/")
async def read_items(db: DBConnection = Depends(get_db)):
# 使用 db 进行数据库操作
return {"items": [{"item_id": "Foo"}]}
File:处理文件上传:与 UploadFile 配合使用,声明文件上传参数。
from fastapi import File, UploadFile
@app.post("/upload-file/")
async def create_upload_file(file: UploadFile = File(...)):
contents = await file.read()
return {"filename": file.filename}
Form:处理表单数据:从表单提交的数据中获取字段值,支持多值和文件上传。
from fastapi import Form
@app.post("/login/")
async def login(username: str = Form(...), password: str = Form(...)):
return {"username": username}
Header:获取请求头:从请求头中获取特定的值,支持自定义头和数据验证。
from fastapi import Header
@app.get("/items/")
async def read_items(user_agent: str = Header(None)):
return {"User-Agent": user_agent}
Path:路径参数:从 URL 路径中获取参数值,支持参数校验和转换。
from fastapi import Path
@app.get("/items/{item_id}")
async def read_item(item_id: int = Path(..., gt=0)):
return {"item_id": item_id}
Query:查询参数:从 URL 查询字符串中获取参数值,支持默认值、别名和数据验证。
from fastapi import Query
@app.get("/items/")
async def read_items(q: str = Query(None, min_length=3)):
return {"q": q}
Security:安全认证:集成安全认证方案,如 OAuth2、API 密钥等,保护 API 资源。
from fastapi import Depends, Security
from fastapi.security import OAuth2PasswordBearer
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
async def get_current_user(token: str = Depends(oauth2_scheme)):
# 验证 token 并获取当前用户
return {"username": "test"}
@app.get("/users/me")
async def read_users_me(current_user: dict = Security(get_current_user)):
return current_user
组合参数处理:将多个参数处理函数组合使用,处理复杂的请求数据结构。
@app.post("/items/{item_id}")
async def update_item(
item_id: int = Path(..., gt=0),
item: Item = Body(...),
q: str = Query(None)
):
return {"item_id": item_id, "item": item.dict(), "q": q}
自定义参数验证逻辑:通过定义 Pydantic 模型的验证方法或使用依赖项,实现自定义的参数验证逻辑。
from pydantic import BaseModel, validator
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
@validator("price")
def price_must_be_positive(cls, v):
if v <= 0:
raise ValueError("Price must be positive")
return v
@app.post("/items/")
async def create_item(item: Item = Body(...)):
return item.dict()
参数处理的性能优化:对参数处理逻辑进行性能优化,如缓存验证结果、减少不必要的计算等。
from functools import lru_cache
@lru_cache(maxsize=100)
def validate_item_id(item_id: int):
if item_id <= 0:
raise ValueError("Item ID must be positive")
return item_id
@app.get("/items/{item_id}")
async def read_item(item_id: int = Path(...)):
validated_id = validate_item_id(item_id)
return {"item_id": validated_id}
参数处理的国际化支持:根据客户端的语言偏好,对参数的错误信息进行多语言转换。
from fastapi import Request
from pydantic import BaseModel
from pydantic.i18n import Translator
translator = Translator("zh")
class Item(BaseModel):
name: str
class Config:
error_msg_templates = {
"value_error.missing": translator("field_required")
}
@app.post("/items/")
async def create_item(item: Item = Body(...)):
return item.dict()
参数处理的扩展功能:通过继承和扩展参数处理函数,实现特定的业务逻辑和功能。
from fastapi.params import Body
from fastapi import Request
class CustomBody(Body):
def __init__(self, default, *, media_type="application/json", **kwargs):
super().__init__(default, media_type=media_type, **kwargs)
async def get_value(self, name: str, request: Request):
# 自定义获取请求体值的逻辑
body = await request.body()
# 解析自定义格式的请求体
return parsed_value
@app.post("/custom-items/")
async def create_custom_item(item: Item = CustomBody(...)):
return item.dict()
Request 对象表示客户端发送的 HTTP 请求,提供了获取请求方法、URL、头、正文等信息的方法。Response 对象用于构建要发送给客户端的 HTTP 响应,支持设置状态码、头、正文等内容。
获取请求信息:通过 Request 对象获取客户端的 IP 地址、用户代理、请求方法等信息。
from fastapi import Request, FastAPI
app = FastAPI()
@app.get("/info/")
async def get_request_info(request: Request):
client_host = request.client.host
user_agent = request.headers.get("User-Agent")
method = request.method
return {"client_host": client_host, "user_agent": user_agent, "method": method}
自定义响应内容:使用 Response 对象构建自定义的响应,包括设置状态码、头和正文。
from fastapi import Response, FastAPI
app = FastAPI()
@app.get("/custom-response/")
async def custom_response():
content = "Custom response content"
headers = {"X-Custom-Header": "value"}
return Response(content=content, status_code=200, headers=headers)
处理请求正文:获取和解析请求的正文内容,支持不同的媒体类型。
@app.post("/process-body/")
async def process_body(request: Request):
body = await request.body()
# 处理请求正文
return {"body_length": len(body)}
重定向响应:发送重定向响应,将客户端引导到另一个 URL。
from fastapi import status
@app.get("/redirect/")
async def redirect():
return Response(status_code=status.HTTP_302_FOUND, headers={"Location": "/new-url/"})
流式响应:对于大文件下载或实时数据推送,使用流式响应逐步发送数据。
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
app = FastAPI()
async def fake_video_streamer():
for i in range(10):
yield b"some fake video bytes"
await asyncio.sleep(0.1)
@app.get("/streaming-video/")
async def streaming_video():
return StreamingResponse(fake_video_streamer(), media_type="video/mp4")
中间件中处理请求与响应:在中间件中对请求和响应进行全局处理,如日志记录、认证授权等。
from fastapi import Request, Response
from fastapi.middleware import Middleware
class LoggingMiddleware:
async def __call__(self, request: Request, call_next):
start_time = time.time()
response = await call_next(request)
process_time = time.time() - start_time
logger.info(
f"{request.method} {request.url} - {response.status_code} - {process_time:.4f}s"
)
return response
app = FastAPI()
app.add_middleware(LoggingMiddleware)
自定义响应类:继承 Response 类创建自定义的响应类型,满足特定的业务需求。
from fastapi.responses import Response
class CustomResponse(Response):
media_type = "application/json"
def __init__(self, content=None, status_code=200, headers=None):
super().__init__(content=content, status_code=status_code, headers=headers)
self.headers["X-Custom-Header"] = "value"
@app.get("/custom-response-class/")
async def custom_response_class():
return CustomResponse(content={"message": "Custom response"})
处理跨域请求:通过设置响应头支持跨域资源共享(CORS),允许不同域的客户端访问 API。
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/cors-enabled/")
async def cors_enabled():
return {"message": "CORS enabled"}
处理文件下载响应:发送文件作为响应,支持断点续传和不同的文件类型。
from fastapi.responses import FileResponse
@app.get("/download-file/")
async def download_file():
file_path = "large-video.mp4"
return FileResponse(
path=file_path,
media_type="video/mp4",
filename="downloaded-video.mp4"
)
响应的缓存控制:通过设置缓存头控制客户端或代理服务器对响应的缓存行为,提高性能和减少带宽消耗。
@app.get("/cached-response/")
async def cached_response():
headers = {"Cache-Control": "max-age=3600, public"}
return Response(content="Cached content", headers=headers)
APIRouter 是 FastAPI 提供的路由管理工具,用于将相关的路由分组到不同的模块或文件中,便于大型应用的组织和维护,同时支持中间件、依赖项等的独立配置。
路由分组:将相关的路由函数组织到一个 APIRouter 实例中,便于模块化开发。
from fastapi import APIRouter, FastAPI
router = APIRouter()
@router.get("/items/")
async def read_items():
return [{"item_id": "Foo"}]
@router.get("/users/")
async def read_users():
return [{"username": "John"}]
app = FastAPI()
app.include_router(router)
路由前缀与标签:为路由组设置统一的前缀和标签,方便 API 文档的组织和阅读。
router = APIRouter(prefix="/api", tags=["items"])
@router.get("/items/")
async def read_items():
return [{"item_id": "Foo"}]
app = FastAPI()
app.include_router(router)
依赖项注入:为路由组设置全局的依赖项,所有路由函数都可以继承使用。
from fastapi import Depends, Security
def get_api_key(api_key: str = Header(...)):
# 验证 API 密钥
return api_key
router = APIRouter(dependencies=[Depends(get_api_key)])
@router.get("/items/")
async def read_items():
return [{"item_id": "Foo"}]
app = FastAPI()
app.include_router(router)
中间件支持:为路由组添加特定的中间件,处理请求和响应的全局逻辑。
from fastapi import Request, Response
class LoggingMiddleware:
async def __call__(self, request: Request, call_next):
start_time = time.time()
response = await call_next(request)
process_time = time.time() - start_time
print(f"Request: {request.method} {request.url} - {process_time:.4f}s")
return response
router = APIRouter()
router.add_middleware(LoggingMiddleware)
@router.get("/items/")
async def read_items():
return [{"item_id": "Foo"}]
app = FastAPI()
app.include_router(router)
路由的版本控制:通过路由前缀或参数实现 API 的版本控制,方便不同版本的兼容和维护。
v1_router = APIRouter(prefix="/v1")
v2_router = APIRouter(prefix="/v2")
@v1_router.get("/items/")
async def read_items_v1():
return [{"item_id": "Foo_v1"}]
@v2_router.get("/items/")
async def read_items_v2():
return [{"item_id": "Foo_v2"}]
app = FastAPI()
app.include_router(v1_router)
app.include_router(v2_router)
动态路由注册:根据配置或数据库动态注册路由,实现灵活的路由管理。
from importlib import import_module
def load_routes(config):
for route_config in config:
module = import_module(route_config["module"])
router = getattr(module, "router")
app.include_router(router, **route_config.get("kwargs", {}))
app = FastAPI()
load_routes(config.ROUTES)
路由的条件注册:根据环境、配置或其他条件决定是否注册某些路由。
if settings.DEBUG:
debug_router = APIRouter()
@debug_router.get("/debug-info/")
async def debug_info():
return {"debug": True}
app.include_router(debug_router)
路由的组合与嵌套:将多个 APIRouter 实例组合或嵌套使用,构建复杂的路由结构。
admin_router = APIRouter(prefix="/admin")
@admin_router.get("/users/")
async def read_admin_users():
return [{"username": "admin"}]
app = FastAPI()
app.include_router(admin_router)
路由的性能监控:为路由组添加性能监控中间件,收集路由的性能数据。
from prometheus_fastapi_instrumentator import Instrumentator
router = APIRouter()
@router.get("/items/")
async def read_items():
return [{"item_id": "Foo"}]
app = FastAPI()
app.include_router(router)
Instrumentator().instrument(app).expose()
路由的访问控制:为路由组设置访问控制逻辑,限制只有授权用户或 IP 地址才能访问。
from fastapi import Request, HTTPException
ALLOWED_IPS = ["127.0.0.1"]
@app.middleware("http")
async def ip_filter(request: Request, call_next):
client_host = request.client.host
if client_host not in ALLOWED_IPS:
raise HTTPException(status_code=403, detail="Forbidden")
response = await call_next(request)
return response
router = APIRouter()
@router.get("/protected-items/")
async def read_protected_items():
return [{"item_id": "Protected"}]
app = FastAPI()
app.include_router(router)
WebSocket 提供了在客户端和服务器之间建立双向通信通道的能力,适用于需要实时交互的应用场景,如聊天应用、在线游戏、实时数据监控等。
建立 WebSocket 连接:通过定义 WebSocket 路由处理函数,接受客户端的连接请求。
from fastapi import WebSocket, FastAPI
app = FastAPI()
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
await websocket.send_text(f"Message text was: {data}")
发送与接收消息:在 WebSocket 连接建立后,发送和接收文本或二进制消息。
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
text_data = await websocket.receive_text()
await websocket.send_text(f"Echo: {text_data}")
bytes_data = await websocket.receive_bytes()
await websocket.send_bytes(bytes_data)
连接管理:维护活动的 WebSocket 连接列表,方便广播消息或处理连接状态变化。
active_connections = []
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
active_connections.append(websocket)
try:
while True:
data = await websocket.receive_text()
for connection in active_connections:
await connection.send_text(data)
except WebSocketDisconnect:
active_connections.remove(websocket)
消息格式处理:对 WebSocket 消息进行序列化和反序列化,支持 JSON、XML 等格式。
import json
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
json_data = await websocket.receive_json()
processed_data = process_json(json_data)
await websocket.send_json(processed_data)
异常处理与连接关闭:捕获 WebSocket 连接过程中的异常,优雅地关闭连接并清理资源。
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
try:
while True:
data = await websocket.receive_text()
await websocket.send_text(f"Message: {data}")
except WebSocketException as e:
print(f"WebSocket error: {e}")
finally:
await websocket.close()
WebSocket 的认证与授权:在 WebSocket 连接建立前或建立后进行认证和授权检查,确保只有合法用户才能访问。
from fastapi import Query
@app.websocket("/ws")
async def websocket_endpoint(
websocket: WebSocket,
token: str = Query(...)
):
# 验证 token
if not validate_token(token):
await websocket.close(code=status.WS_1008_POLICY_VIOLATION)
return
await websocket.accept()
# 处理连接
WebSocket 的负载均衡与扩展:在高并发场景下,通过负载均衡器将 WebSocket 连接分发到多个服务器实例,提高系统的可扩展性。
import aioredis
redis = aioredis.from_url("redis://localhost")
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
# 订阅 Redis 通道
async def pubsub_listener(channel):
async for message in channel.iter():
await websocket.send_text(message.decode())
pubsub = redis.pubsub()
await pubsub.subscribe("broadcast")
asyncio.create_task(pubsub_listener(pubsub))
try:
while True:
data = await websocket.receive_text()
# 发布消息到 Redis 通道
await redis.publish("broadcast", data)
except WebSocketDisconnect:
await pubsub.unsubscribe("broadcast")
WebSocket 的性能优化:对 WebSocket 连接进行性能优化,如减少消息的序列化开销、使用二进制帧传输等。
import protobuf # 假设已定义好 protobuf 消息格式
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
bytes_data = await websocket.receive_bytes()
message = protobuf.Message()
message.ParseFromString(bytes_data)
# 处理消息
response = protobuf.Response()
response_data = response.SerializeToString()
await websocket.send_bytes(response_data)
WebSocket 的监控与日志:记录 WebSocket 连接的活动日志,监控连接数、消息吞吐量等指标,便于性能分析和故障排查。
from prometheus_client import Counter, Gauge
ws_connections = Gauge("websocket_connections", "Number of active WebSocket connections")
ws_messages = Counter("websocket_messages", "Total number of WebSocket messages", labelnames=["type"])
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
ws_connections.inc()
try:
while True:
data = await websocket.receive_text()
ws_messages.labels("text").inc()
await websocket.send_text(data)
except WebSocketDisconnect:
ws_connections.dec()
WebSocket 的安全增强:采取措施防止 WebSocket 连接被恶意利用,如限制消息大小、防止 XSS 攻击等。
MAX_MESSAGE_SIZE = 1024 * 1024 # 1MB
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
if len(data) > MAX_MESSAGE_SIZE:
await websocket.close(code=status.WS_1009_MESSAGE_TOO_BIG)
break
# 处理消息