Есть ли способ проверить заголовок запроса с помощью декоратора в FastAPI?

#python #http #request #decorator #fastapi

Вопрос:

В настоящее время я рассматриваю примеры проверки заголовков входящих запросов, представленных в документах 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)
 

Я знаком с тем, как я должен обрабатывать параметры в декораторе, может ли кто-нибудь помочь?

Ответ №1:

Вместо прямой ссылки на 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/и т. Д.