FastAPI-响应处理和配置
前篇学习了关于请求参数相关的约束验证, Request
包括 路径参数 , 查询参数, 枚举参数, 文件参数, 类型验证, 多参数嵌套验证, 请求体嵌套验证, Cookie 和 Header 等, 了解完这些对于接口的请求基本就到位了.
这篇便主要针对响应处理进行介绍 Response
项目结构
主要来自慕课网的学习公开课笔记, 目录结构如下:
base
- __ init __.py
- base_01.py
- base_02.py
- base_03.py
- base_04.py
- ...
main.py
其中 main.py 的内容如下:
from fastapi import FastAPI
import uvicorn
from base import app01
from base import app02
from base import app03
from base import app04
app = FastAPI(
title="FastAPI 基础教程",
version='1.0.0',
docs_url='/docs'
)
app.include_router(app01, prefix='/app01', tags=['请求参数和验证'])
app.include_router(app02, prefix='/app02', tags=['响应处理和配置'])
app.include_router(app03, prefix='/app03', tags=['依赖注入和系统'])
app.include_router(app04, prefix='/app04', tags=['安全认证和授权'])
if __name__ == '__main__':
uvicorn.run('main:app', host='0.0.0.0', port=8000, reload=True, workers=1)
响应体处理 Response
对应的资源引入, 主要是表达, 文件上传, 异常类, 模型类, 类型校验等如下:
# app02.py
from fastapi import APIRouter, status, Form, File, UploadFile, HTTPException
from typing import Optional, List, Union
from pydantic import BaseModel, EmailStr
app02 = APIRouter()
响应模型类 response_model
演示用一个常用的用户信息类, 包含用户的姓名, 昵称, 电话, 邮箱, 地址等
# 用户信息基类 (共有)
class User(BaseModel):
username: str
email: EmailStr # pip install pydantic[email]
mobile: str = '10086' # 真实项目中, 可用 Field 做正则校验
full_name: Optional[str] = None
address: str = None
# 用户信息输入类, 会多输入一个密码
class UserIn(User):
password: str
# 用户信息输出类, 不返回密码, 其他都返回
class UserOut(User):
pass
# 用户数据模拟
users = {
"user01": { 'username': 'cj', 'password': 123123, 'email': 'user01@example.com' },
"user02": { 'username': 'youge', 'password': 123456, 'email': 'user02@example.com' }
}
请求用户信息响应, 前端输入是一个post请求 UerIn, 响应的模型是 UserOut .
@app02.post('/response_model', response_model=UserOut, response_model_exclude_unset=True)
async def response_model(user: UserIn):
"""response_model_exclude_unset=True 表示不用默认值, 前端传啥用啥"""
print(user.password, "密码不会被返回的")
return users['user01']
响应属性:
@app02.post('/response_model/attributes',
# response_model=UserOut
# response_model=Union[UserIn, UserOut]
response_model=List[UserOut]
# response_model_include=['username', 'email'],
# response_model_exclude=['mobile']
)
可以进行合并, 选择等灵活操作. 比如我们要返回 UserIn 和 UserOut 但密码不返回, 也是可以取巧处理的.
async def response_model_attributes(user: UserIn):
# Union[UserIn, UserOut] 后, 删掉 password 也能返回成功的
del user.password
return [user, user]
响应状态码 status
查看它的源码其实就是对类似 200, 404, 500 等响应码进行语义化而已, 其实也多此一举我觉得.
@app02.post('/status_code', status_code=200)
async def status_code():
return { 'status_code': 200 }
@app02.post('/status_attribute', status_code=status.HTTP_200_OK)
async def status_attribute():
print(type(status.HTTP_200_OK))
return { 'status_code': status.HTTP_200_OK }
这里的 status.HTTP_200_OK
, 其实就是数字 200.
表单数据处理 Form
请求和响应都经常会用到, 最多的就是注册, 登录相关,
注意这里用 Form 类则需要 pip install python-multipart
@app02.post('/login')
async def login(username: str = Form(...), password: str = Form(..., regex='^a')):
# Form 类的校验方法类似 Path, Query, Cookie, Header 等
# 走完认证逻辑后, 返回用户名
return { 'username': username }
curl -X 'POST' \
'http://127.0.0.1:8000/app02/login' \
-H 'accept: application/json' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'username=admin&password=admin'
单/多/大文件上传处理 File, UploadFile
@app02.post('/file')
async def file(file: bytes = File(...)):
# async def file(file: List[bytes] = File(...)):
"""使用 File 类, 文件内容会议 bytes 形式读入内存, 适合小文件上传"""
return { 'file_size': len(file) }
@app02.post('/upload_files')
async def upload_files(files: List[UploadFile] = File(...)):
"""
使用 UploadFile 类的优势:
1. 文件优先存在内存, 如果达到阈值后, 将被保存在磁盘中
2. 适合于图片, 视频等大文件
3. 可以获取上传文件的元数据, 如文件名, 创建时间等
4. 有文件对象的异步接口
5. 上传的文件是 Pyhon 文件对象, 可以使用 write(), read(), seek(), close() 等操作
"""
for file in files:
contents = await file.read()
print('文件的内容是: ', contents)
return { 'filename': files[0].filename, 'content_type': files[0].content_type }
接口文档配置
@app02.post(
'/path_operation_configuration',
response_model=UserOut,
# tags=["Path", "Operation", "Configuration"],
summary="This is summary",
description="这是一个描述哈",
response_description="给前端响应一个描述",
deprecated=True,
status_code=status.HTTP_200_OK
)
async def path_operation_configuration(user: UserIn):
"""
路径操作配置
请求: 用户信息
响应: 返回结果
"""
return user
应用文档配置
# main.py
app = FastAPI(
title="FastAPI 基础教程",
version='1.0.0',
docs_url='/docs'
)
异常类处理 HTTPException
这些都是很常见的操作了, 简单粗暴.
@app02.get('/http_exception')
async def http_exception(city: str):
if city != 'Beijing':
raise HTTPException(status_code=404, headers={ "X-Error": "Error" }, detail="City not found")
return { 'city': city }
这样关于响应模块的也就基本差不多了, 当然在实际应用中, 响应要怎么弄其实都看自己灵活配置, 重点还是请求校验这块更为关键哦.
耐心和恒心, 总会获得回报的.