FastAPI 有提供 Request 模块,但其实就是 starlette 里面的 Request
FastAPI 有提供 Response 模块,但其实就是 starlette 里面的 Response
import time
from fastapi import FastAPI, Request
@app.middleware("http")
# 必须用 async
async def add_process_time_header(request: Request, call_next):
start_time = time.time()
# 必须用 await
response = await call_next(request)
process_time = time.time() - start_time
# 自定义请求头
response.headers["X-Process-Time"] = str(process_time)
# 返回响应
return response
import uvicorn
from fastapi import FastAPI, Request, Query, Body, status
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel
app = FastAPI()
@app.middleware("http")
# 必须用 async
async def add_process_time_header(request: Request, call_next):
# 1、可针对 Request 或其他功能,自定义代码块
print("=== 针对 request 或其他功能执行自定义逻辑代码块 ===")
print(request.query_params)
print(request.method)
# 2、将 Request 传回给对应的路径操作函数继续处理请求
# 必须用 await
response = await call_next(request)
# 4、接收到路径操作函数所产生的的 Response,记住这并不是返回值(return)
# 5、可针对 Response 或其他功能,自定义代码块
print("*** 针对 response 或其他功能执行自定义逻辑 ***")
# 自定义请求头响应状态码
response.headers["X-Process-Token"] = str("test_token_polo")
response.status_code = status.HTTP_202_ACCEPTED
# 6、最终返回 Response 给客户端
return response
class User(BaseModel):
name: str = None
age: int = None
@app.post("/items/")
async def read_item(item_id: str = Query(...), user: User = Body(...)):
# 3、收到请求,处理请求
res = {"item_id": item_id}
if user:
res.update(jsonable_encoder(user))
print("@@@ 执行路径操作函数 @@@", res)
# 有没有 return 都不影响中间件接收 Response
return res
=== 针对 request 或其他功能执行自定义逻辑代码块 ===
item_id=test
POST
@@@ 执行路径操作函数 @@@ {'item_id': 'test', 'name': 'string', 'age': 0}
*** 针对 response 或其他功能执行自定义逻辑 ***
自定义的请求头和响应码已经生效啦