Reputation: 765
I am now developing with FastAPI and SQLAlchemy Core 1.4.
I've got my API function.
async def do_something(
...
current_user: dict = Depends(get_superuser),
conn: AsyncConnection = Depends(engine_begin),
):
...
do_something
API depends on get_superuser
and SQLAlchemy connection by engine_begin
.
I am planning on sub-dependencies like this:
do_something
-> get_superuser
-> get_current_user
get_current_user
dependency is not required to access database during JWT validation.
However, get_superuser
is required to access database to check permissions or something else.
async def get_superuser(
current_user: dict = Depends(get_current_user),
conn: AsyncConnection = Depends(engine_connect),
) -> dict:
...
return {
"superuser": row._mapping,
"conn": conn,
}
I was able to make get_superuser
depends on get_current_user
and engine_begin
, and returned dict { superuser: dict, conn: connection } as shown above.
Personally it does not make sense if get_superuser
returns database connection, too.
I tried to put the path decorator dependencies=[Depends(engine_begin)]
Then, I could not get the connection handle.
Another solution might be double dependencies like do_something
depends on engine_begin
and get_superuser
depends on engine_begin
. I think it will cause another problem due to nested transaction begin.
I would like to know if there is a clear way to check authorization/permission after authentication.
Thank you.
Upvotes: 1
Views: 3572
Reputation: 52892
FastAPI will not evaluate a dependency multiple times - so your database connection will only be initialized once.
There shouldn't be any issue with having multiple dependency references such as conn: AsyncConnection = Depends(engine_connect)
. It just says that "I need the dependency returned by this function"; any subsequent calls will return the same created dependency.
If one of your dependencies is declared multiple times for the same path operation, for example, multiple dependencies have a common sub-dependency, FastAPI will know to call that sub-dependency only once per request.
And it will save the returned value in a "cache" and pass it to all the "dependants" that need it in that specific request, instead of calling the dependency multiple times for the same request.
In an advanced scenario where you know you need the dependency to be called at every step (possibly multiple times) in the same request instead of using the "cached" value, you can set the parameter
use_cache=False
when usingDepends
So your assumption "I think it will cause another problem due to nested transaction begin." is wrong: it's the suggested way of handling requiring the same dependency in multiple locations.
This allows you to compose your dependencies in a very visible and helpful way, and they only get resolved if they're actually necessary somewhere in the hierarchy.
Upvotes: 3