-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
68 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
from __future__ import annotations | ||
|
||
from typing import TYPE_CHECKING | ||
|
||
from fastapi.routing import APIRoute | ||
|
||
from wireup import DependencyContainer, container, warmup_container | ||
from wireup.integration.util import is_view_using_container | ||
|
||
if TYPE_CHECKING: | ||
from types import ModuleType | ||
|
||
from fastapi import FastAPI | ||
|
||
|
||
def wireup_init_fastapi_integration( | ||
app: FastAPI, | ||
service_modules: list[ModuleType], | ||
dependency_container: DependencyContainer = container, | ||
) -> None: | ||
"""Integrate wireup with a fastapi application. | ||
This must be called once all views have been registered. | ||
Decorates all views where container objects are being used making | ||
the `@container.autowire` decorator no longer needed. | ||
:param app: The application instance | ||
:param service_modules: A list of python modules where application services reside. These will be loaded to trigger | ||
container registrations. | ||
:param dependency_container: The instance of the dependency container. | ||
The default wireup singleton will be used when this is unset. | ||
This will be a noop and have no performance penalty for views which do not use the container. | ||
""" | ||
warmup_container(dependency_container, service_modules or []) | ||
|
||
for route in app.routes: | ||
if ( | ||
isinstance(route, APIRoute) | ||
and route.dependant.call | ||
and is_view_using_container(dependency_container, route.dependant.call) | ||
): | ||
route.dependant.call = dependency_container.autowire(route.endpoint) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import inspect | ||
from typing import Any, Callable | ||
|
||
from wireup import DependencyContainer | ||
from wireup.ioc.types import InjectableType | ||
from wireup.ioc.util import parameter_get_type_and_annotation | ||
|
||
|
||
def is_view_using_container(dependency_container: DependencyContainer, view: Callable[..., Any]) -> bool: | ||
"""Determine whether the view is using the given dependency container.""" | ||
if hasattr(view, "__annotations__"): | ||
for dep in inspect.signature(view).parameters.values(): | ||
param = parameter_get_type_and_annotation(dep) | ||
|
||
is_requesting_injection = isinstance(param.annotation, InjectableType) | ||
if is_requesting_injection or (param.klass and dependency_container.is_type_known(param.klass)): | ||
return True | ||
|
||
return False |