Hi, great web-framework, great work! :fire: I am in process of moving one of the backends from Flask to FastAPI and I was wondering is FastAPI using cache when dealing with auth (example below)? Password can change, somebody can delete the user or change his privileges, I hope it does not use cache in my case. Where do I put use_cache=False if it does?
async def get_user(security_scopes: SecurityScopes, credentials: HTTPBasicCredentials = Depends(_security)) -> User:
"""
Get user from DB and check if they are authorized to do what is in security_scopes.
I implement my own caching logic here and check if user was changed in DB.
"""
# /token endpoint
async def token(user: User = Depends(get_user)) -> JSONResponse:
"""Use Basic Auth to get token."""
# /users/{user_id} endpoint
async def get_user_by_id(user_id: int, user: User = Security(get_user, scopes=["users:read"])):
'''Get user by ID'''
Thanks a lot! :smile:
The parameter use_cache defaults to True, as we can see from FastAPI's Security function:
def Security( # noqa: N802
dependency: Callable = None, *, scopes: Sequence[str] = None, use_cache: bool = True
) -> Any:
return params.Security(dependency=dependency, scopes=scopes, use_cache=use_cache)
You can pass it directly to Security, such as:
```
async def get_user_by_id(user_id: int, user: User = Security(get_user, scopes=["users:read"], use_cache=False)):
'''Get user by ID'''
Thanks, @mlaradji ! If I need to pass use_cache=False to every endpoint explicitly - it is better to create function that does that for me :thinking:
def BetterSecurity(dependency: Callable = None, *, scopes: Sequence[str] = None) -> Any:
return params.Security(dependency=dependency, scopes=scopes, use_cache=False)
Solution that should work and a bit cleaner:
async def get_user(security_scopes: SecurityScopes, credentials: HTTPBasicCredentials = Depends(_security)) -> User:
"""
Get user from DB and check if they are authorized to do what is in security_scopes.
I implement my own caching logic here and check if user was changed in DB.
"""
def Auth(scopes: Sequence[str] = None) -> Any:
return params.Security(dependency=get_user, scopes=scopes, use_cache=False)
# /users/{user_id} endpoint
async def get_user_by_id(user_id: int, user: User = Auth(scopes=["users:read"])):
'''Get user by ID'''
Hey, you don't really need to disable the cache. That cache is only used per-request. It only avoids, for example, getting the user from DB several times in dependencies and sub-dependencies to handle a single request.
But all that will be executed again for the next request. So it's fine to leave it. You should set use_cache=False only when you have some specific reason to make a dependency function execute more than once in a single request.
In fact, I have never found a real use case for it. I thought there would be one at some point, but it hasn't happened so far. :shrug: