|
|
|
@ -53,8 +53,16 @@ from fastapi.concurrency import ( |
|
|
|
asynccontextmanager, |
|
|
|
contextmanager_in_threadpool, |
|
|
|
) |
|
|
|
from fastapi.dependencies.models import EndpointDependant, LifespanDependant, SecurityRequirement |
|
|
|
from fastapi.exceptions import DependencyScopeError, InvalidDependencyScope, UninitializedLifespanDependency |
|
|
|
from fastapi.dependencies.models import ( |
|
|
|
EndpointDependant, |
|
|
|
LifespanDependant, |
|
|
|
SecurityRequirement, |
|
|
|
) |
|
|
|
from fastapi.exceptions import ( |
|
|
|
DependencyScopeError, |
|
|
|
InvalidDependencyScope, |
|
|
|
UninitializedLifespanDependency, |
|
|
|
) |
|
|
|
from fastapi.logger import logger |
|
|
|
from fastapi.security.base import SecurityBase |
|
|
|
from fastapi.security.oauth2 import OAuth2, SecurityScopes |
|
|
|
@ -122,7 +130,7 @@ def ensure_multipart_is_installed() -> None: |
|
|
|
|
|
|
|
|
|
|
|
def get_parameterless_sub_dependant( |
|
|
|
*, depends: params.Depends, path: str, caller: Callable[..., Any], index: int |
|
|
|
*, depends: params.Depends, path: str, caller: Callable[..., Any], index: int |
|
|
|
) -> Union[EndpointDependant, LifespanDependant]: |
|
|
|
assert callable(depends.dependency), ( |
|
|
|
"A parameter-less dependency must have a callable dependency" |
|
|
|
@ -135,7 +143,7 @@ def get_parameterless_sub_dependant( |
|
|
|
path=path, |
|
|
|
call=depends.dependency, |
|
|
|
security_scopes=use_security_scopes, |
|
|
|
index=index |
|
|
|
index=index, |
|
|
|
) |
|
|
|
elif depends.scope == "lifespan": |
|
|
|
return get_lifespan_dependant( |
|
|
|
@ -146,8 +154,7 @@ def get_parameterless_sub_dependant( |
|
|
|
) |
|
|
|
else: |
|
|
|
raise InvalidDependencyScope( |
|
|
|
f'Dependency "{index}" of {caller} has an invalid ' |
|
|
|
f'scope: "{depends.scope}"' |
|
|
|
f'Dependency "{index}" of {caller} has an invalid scope: "{depends.scope}"' |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
@ -267,7 +274,7 @@ def get_lifespan_dependant( |
|
|
|
raise DependencyScopeError( |
|
|
|
f'Dependency "{dependant.name}" has "lifespan" scope, but was defined' |
|
|
|
f'with an invalid argument: "{param_name}" which is ' |
|
|
|
f'not a valid sub-dependency. Lifespan scoped dependencies may only ' |
|
|
|
f"not a valid sub-dependency. Lifespan scoped dependencies may only " |
|
|
|
f"use lifespan scoped sub-dependencies." |
|
|
|
) |
|
|
|
|
|
|
|
@ -275,7 +282,7 @@ def get_lifespan_dependant( |
|
|
|
raise DependencyScopeError( |
|
|
|
f'Dependency "{dependant.name}" has "lifespan" scope, but was defined with the ' |
|
|
|
f'sub-dependency "{param_name}" which has "{param_details.depends.scope}" scope. Lifespan scoped ' |
|
|
|
f'dependencies may only use lifespan scoped sub-dependencies.' |
|
|
|
f"dependencies may only use lifespan scoped sub-dependencies." |
|
|
|
) |
|
|
|
|
|
|
|
assert param_details.depends.dependency is not None |
|
|
|
@ -346,23 +353,27 @@ def get_endpoint_dependant( |
|
|
|
if param_details.depends.scopes: |
|
|
|
use_security_scopes.extend(param_details.depends.scopes) |
|
|
|
if param_details.depends.scope == "lifespan": |
|
|
|
dependant.lifespan_dependencies.append(get_lifespan_dependant( |
|
|
|
caller=call, |
|
|
|
call=param_details.depends.dependency, |
|
|
|
name=param_name, |
|
|
|
use_cache=param_details.depends.use_cache, |
|
|
|
index=index |
|
|
|
)) |
|
|
|
dependant.lifespan_dependencies.append( |
|
|
|
get_lifespan_dependant( |
|
|
|
caller=call, |
|
|
|
call=param_details.depends.dependency, |
|
|
|
name=param_name, |
|
|
|
use_cache=param_details.depends.use_cache, |
|
|
|
index=index, |
|
|
|
) |
|
|
|
) |
|
|
|
elif param_details.depends.scope in ("request", "function", None): |
|
|
|
dependant.endpoint_dependencies.append(get_endpoint_dependant( |
|
|
|
path=path, |
|
|
|
call=param_details.depends.dependency, |
|
|
|
name=param_name, |
|
|
|
security_scopes=use_security_scopes, |
|
|
|
use_cache=param_details.depends.use_cache, |
|
|
|
index=index, |
|
|
|
scope=param_details.depends.scope |
|
|
|
)) |
|
|
|
dependant.endpoint_dependencies.append( |
|
|
|
get_endpoint_dependant( |
|
|
|
path=path, |
|
|
|
call=param_details.depends.dependency, |
|
|
|
name=param_name, |
|
|
|
security_scopes=use_security_scopes, |
|
|
|
use_cache=param_details.depends.use_cache, |
|
|
|
index=index, |
|
|
|
scope=param_details.depends.scope, |
|
|
|
) |
|
|
|
) |
|
|
|
else: |
|
|
|
raise InvalidDependencyScope( |
|
|
|
f'Dependency "{name}" of {call} has an invalid ' |
|
|
|
@ -628,7 +639,10 @@ def add_param_to_fields(*, field: ModelField, dependant: EndpointDependant) -> N |
|
|
|
|
|
|
|
|
|
|
|
async def _solve_generator( |
|
|
|
*, dependant: Union[EndpointDependant, LifespanDependant], stack: AsyncExitStack, sub_values: Dict[str, Any] |
|
|
|
*, |
|
|
|
dependant: Union[EndpointDependant, LifespanDependant], |
|
|
|
stack: AsyncExitStack, |
|
|
|
sub_values: Dict[str, Any], |
|
|
|
) -> Any: |
|
|
|
assert dependant.call |
|
|
|
if dependant.is_gen_callable: |
|
|
|
@ -690,7 +704,9 @@ async def solve_lifespan_dependant( |
|
|
|
|
|
|
|
if dependant_to_solve.is_gen_callable or dependant_to_solve.is_async_gen_callable: |
|
|
|
value = await _solve_generator( |
|
|
|
dependant=dependant_to_solve, stack=async_exit_stack, sub_values=dependency_arguments |
|
|
|
dependant=dependant_to_solve, |
|
|
|
stack=async_exit_stack, |
|
|
|
sub_values=dependency_arguments, |
|
|
|
) |
|
|
|
elif dependant_to_solve.is_coroutine_callable: |
|
|
|
value = await call(**dependency_arguments) |
|
|
|
|