6

FastAPI 0.68.0

Python 3.8

from fastapi import Depends, FastAPI, Header, HTTPException


async def verify_key(x_key: str = Header(...)):
    if x_key != "fake-super-secret-key":
        raise HTTPException(status_code=400, detail="X-Key header invalid")
    return x_key



app = FastAPI(dependencies=[Depends(verify_key)])



@app.get("/items/")
async def read_items():

    return [{"item": "Portal Gun"}, {"item": "Plumbus"}]


This is a example from FastAPI doucuments (Omit part of the code)

Is there any way to get x_key in read_items()

xiº
  • 4,605
  • 3
  • 28
  • 39
A_zc
  • 61
  • 1
  • 3
  • Inject it as a parameter? – abdusco Aug 18 '21 at 05:44
  • @abdusco In the read_items method , i want to return like [{'new_key': x_key+'123'}], it need get x_key from verify_key . What should i do – A_zc Aug 18 '21 at 06:12
  • `async def read_items(x_key: str = Depends(verify_key)): ...` – abdusco Aug 18 '21 at 06:14
  • Does this answer your question? [Inject parameter to every route of an APIRouter using FastAPI](https://stackoverflow.com/questions/74104478/inject-parameter-to-every-route-of-an-apirouter-using-fastapi) – Chris Oct 26 '22 at 12:39

2 Answers2

8
from fastapi import Request, Depends

async def verify_key(request: Request, x_key: str = Header(...)):
    if x_key != "fake-super-secret-key":
        raise HTTPException(status_code=400, detail="X-Key header invalid")

    # save x_key
    request.state.x_key = x_key
    return x_key


app = FastAPI(dependencies=[Depends(verify_key)])


@app.get("/items/")
async def read_items(request: Request):
    # get 'x_key' from request.state
    x_key = request.state.x_key
    return [{"item": "Portal Gun"}, {"item": "Plumbus"}]

flask/bottle mimic

# current_request.py
import contextvars
from fastapi import Request

_CURRENT_REQUEST = contextvars.ContextVar("_CURRENT_REQUEST", default=None)

class CurrentRequest:

    def __getattr__(self, a):
        current_request = _CURRENT_REQUEST.get()
        if current_request is None:
            raise RuntimeError('Out of context')
        return getattr(current_request, a)

request: Request = CurrentRequest()

async def set_current_request(request: Request):
    _CURRENT_REQUEST.set(request)


# fastapi app/subroute 
from fastapi import Request, Depends

from .current_request import request, set_current_request


async def verify_key(x_key: str = Header(...)):
    if x_key != "fake-super-secret-key":
        raise HTTPException(status_code=400, detail="X-Key header invalid")

    # save x_key
    request.state.x_key = x_key
    return x_key


# ! set_current_request should go first
app = FastAPI(dependencies=[Depends(set_current_request), Depends(verify_key)])


@app.get("/items/")
async def read_items():
    # get 'x_key' from request.state
    x_key = request.state.x_key
    return [{"item": "Portal Gun"}, {"item": "Plumbus"}]

Val K
  • 375
  • 2
  • 9
  • thanks for your answer. just one question why you are using async call to verify the token. +1 vote – sib10 Aug 04 '22 at 09:56
2

You can inject verify_key function into read_items as dependency to read its value:

from fastapi import Depends

async def verify_key(x_key: str = Header(...)):
    ...

@app.get("/items/")
async def read_items(key: str = Depends(verify_key)):
    // use key
abdusco
  • 9,700
  • 2
  • 27
  • 44
  • 3
    This way can be done.But if i have many interface methods need depends verify_key,maybe global dependencies is best... – A_zc Aug 18 '21 at 06:39
  • You can't use a global, like you could with flask (you can, but it could lead to undefined behavior). You have to explicitly fetch the value from somewhere – abdusco Aug 18 '21 at 06:41
  • i get it. Thanks for your help. – A_zc Aug 18 '21 at 06:43