我目前正在查看FastAPI文档中提供的检查传入请求头的示例。
我想知道是否有一种方法可以在路由上使用装饰器来实现头检查,而不是在每个端点函数中重复检查代码?比如:
def check_header_api_key(func, *args, **kwargs):
@wraps(func)
def wrapper(request: Request):
if request.headers["SECRET"] != SECRET_KEY:
raise HTTPException(status_code=401, detail="Invalid client secret")
return func(request, *args, **kwargs)
return wrapper
@app.post("/course", response_model=schemas.Course, status_code=200)
@check_header_api_key
def create_course(course: schemas.CourseCreate, request: Request, db: Session = Depends(get_db)):
db_course = crud.get_course(db, course=course)
if db_course:
raise HTTPException(status_code=400, detail="This course has already been created.")
return crud.create_course(db=db, course=course)
我很熟悉我应该如何处理参数进入装饰器,有人可以帮助吗?
不直接引用app
对象,你可以创建一个APIRouter
对象,并将其作为整个路由器的依赖项:
authenticated = APIRouter(dependencies=[Depends(get_authenticated_user)])
你可以给路由器添加端点:
@authenticated.post('/course', ....)
你可以按照你的意愿组合这些路由器对象,要么直接在你的app
下,要么作为彼此的子路由器:
app.include_router(authenticated)
# or with several sub routers:
authenticated_router = APIRouter(dependencies=[Depends(get_authenticated_user)])
public_router = APIRouter()
authenticated_router.include_router(courses.authenticated)
authenticated_router.include_router(users.authenticated)
public_router.include_router(users.public)
app.include_router(authenticated_router)
app.include_router(public_router)
这样你就可以根据需要组合和移动你的路由器,使它们需要或不需要身份验证,你可以进一步扩展它们到admin/private/etc。
解决了同样的问题。FastAPI将request
处理程序传递给kwargs
。如果您需要解析它,您的代码应该如下所示:
from fastapi import FastAPI, Request
from fastapi import HTTPException
def check_header_api_key(func):
@wraps(func)
def wrapper(request, *args, **kwargs):
if request.headers.get("SECRET", None) != SECRET_KEY:
raise HTTPException(status_code=401, detail="Invalid client secret")
return func(*args, **kwargs)
return wrapper
@app.post("/course", response_model=schemas.Course, status_code=200)
@check_header_api_key
def create_course(request: Request, course: schemas.CourseCreate, db: Session = Depends(get_db)):
db_course = crud.get_course(db, course=course)
if db_course:
raise HTTPException(status_code=400, detail="This course has already been created.")
return crud.create_course(db=db, course=course)