From d37ae8e7db322b69a400770f02f41f0c9b979fc5 Mon Sep 17 00:00:00 2001 From: Roman Mogylatov Date: Tue, 17 Nov 2020 23:44:32 -0500 Subject: [PATCH 1/4] Improve FastAPI integration --- docs/main/changelog.rst | 4 ++++ src/dependency_injector/wiring.py | 21 ++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/docs/main/changelog.rst b/docs/main/changelog.rst index eebf8b67..81ece652 100644 --- a/docs/main/changelog.rst +++ b/docs/main/changelog.rst @@ -7,6 +7,10 @@ that were made in every particular version. From version 0.7.6 *Dependency Injector* framework strictly follows `Semantic versioning`_ +Develop +------- +- Improve ``FastAPI`` integration: handle ``Depends(Provide[...])``. + 4.4.0 ----- - Add ``@inject`` decorator. It helps to fix a number of wiring bugs and make wiring be more resilient. diff --git a/src/dependency_injector/wiring.py b/src/dependency_injector/wiring.py index 1ba73639..6752f106 100644 --- a/src/dependency_injector/wiring.py +++ b/src/dependency_injector/wiring.py @@ -27,6 +27,13 @@ else: ... +try: + from fastapi.params import Depends as FastAPIDepends + fastapi_installed = True +except ImportError: + fastapi_installed = False + + from . import providers @@ -320,10 +327,15 @@ def _fetch_reference_injections( injections = {} closing = {} for parameter_name, parameter in signature.parameters.items(): - if not isinstance(parameter.default, _Marker): + if not isinstance(parameter.default, _Marker) \ + and not _is_fastapi_depends(parameter.default): continue + marker = parameter.default + if _is_fastapi_depends(marker): + marker = marker.dependency + if isinstance(marker, Closing): marker = marker.provider closing[parameter_name] = marker @@ -435,6 +447,10 @@ def _is_fastapi_default_arg_injection(injection, kwargs): return injection in kwargs and isinstance(kwargs[injection], _Marker) +def _is_fastapi_depends(param: Any) -> bool: + return fastapi_installed and isinstance(param, FastAPIDepends) + + def _is_patched(fn): return getattr(fn, '__wired__', False) is True @@ -459,6 +475,9 @@ class _Marker(Generic[T], metaclass=ClassGetItemMeta): def __class_getitem__(cls, item) -> T: return cls(item) + def __call__(self) -> T: + return self + class Provide(_Marker): ... From 950d5a5e6e224cdfc3e16eee9cdaa166de3bd113 Mon Sep 17 00:00:00 2001 From: Roman Mogylatov Date: Tue, 17 Nov 2020 23:46:30 -0500 Subject: [PATCH 2/4] Update FastAPI example --- docs/main/changelog.rst | 1 + examples/miniapps/fastapi/README.rst | 4 +-- .../fastapi/giphynavigator/application.py | 2 +- .../fastapi/giphynavigator/endpoints.py | 31 +++++++++++++++++-- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/docs/main/changelog.rst b/docs/main/changelog.rst index 81ece652..0b4b6da1 100644 --- a/docs/main/changelog.rst +++ b/docs/main/changelog.rst @@ -10,6 +10,7 @@ follows `Semantic versioning`_ Develop ------- - Improve ``FastAPI`` integration: handle ``Depends(Provide[...])``. +- Update ``FastAPI`` example. 4.4.0 ----- diff --git a/examples/miniapps/fastapi/README.rst b/examples/miniapps/fastapi/README.rst index 20dbf7e5..96291ae9 100644 --- a/examples/miniapps/fastapi/README.rst +++ b/examples/miniapps/fastapi/README.rst @@ -113,9 +113,9 @@ The output should be something like: giphynavigator/__init__.py 0 0 100% giphynavigator/application.py 13 0 100% giphynavigator/containers.py 6 0 100% - giphynavigator/endpoints.py 6 0 100% + giphynavigator/endpoints.py 20 0 100% giphynavigator/giphy.py 14 9 36% giphynavigator/services.py 9 1 89% giphynavigator/tests.py 38 0 100% --------------------------------------------------- - TOTAL 86 10 88% + TOTAL 100 10 90% diff --git a/examples/miniapps/fastapi/giphynavigator/application.py b/examples/miniapps/fastapi/giphynavigator/application.py index 805f4868..8a8f8a52 100644 --- a/examples/miniapps/fastapi/giphynavigator/application.py +++ b/examples/miniapps/fastapi/giphynavigator/application.py @@ -14,7 +14,7 @@ def create_app() -> FastAPI: app = FastAPI() app.container = container - app.add_api_route('/', endpoints.index) + app.include_router(endpoints.router) return app diff --git a/examples/miniapps/fastapi/giphynavigator/endpoints.py b/examples/miniapps/fastapi/giphynavigator/endpoints.py index 1d52b2f8..ab4f1b88 100644 --- a/examples/miniapps/fastapi/giphynavigator/endpoints.py +++ b/examples/miniapps/fastapi/giphynavigator/endpoints.py @@ -1,17 +1,42 @@ """Endpoints module.""" +from typing import Optional, List + +from fastapi import APIRouter, Depends +from pydantic import BaseModel from dependency_injector.wiring import inject, Provide +from .services import SearchService from .containers import Container +class Gif(BaseModel): + url: str + + +class Response(BaseModel): + query: str + limit: int + gifs: List[Gif] + + +router = APIRouter() + + +@router.get('/', response_model=Response) @inject async def index( - query: str = Provide[Container.config.default.query], - limit: int = Provide[Container.config.default.limit.as_int()], - search_service=Provide[Container.search_service], + query: Optional[str] = None, + limit: Optional[str] = None, + default_query: str = Depends(Provide[Container.config.default.query]), + default_limit: int = Depends(Provide[Container.config.default.limit.as_int()]), + search_service: SearchService = Depends(Provide[Container.search_service]), ): + query = query or default_query + limit = limit or default_limit + gifs = await search_service.search(query, limit) + return { 'query': query, 'limit': limit, From 49921dcf9d1dd33e8825423396328bc9fc2b3de4 Mon Sep 17 00:00:00 2001 From: Roman Mogylatov Date: Tue, 17 Nov 2020 23:50:56 -0500 Subject: [PATCH 3/4] Remove a typo from the Flask tutorial --- docs/main/changelog.rst | 1 + docs/tutorials/flask.rst | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/main/changelog.rst b/docs/main/changelog.rst index 0b4b6da1..8a44cf1b 100644 --- a/docs/main/changelog.rst +++ b/docs/main/changelog.rst @@ -11,6 +11,7 @@ Develop ------- - Improve ``FastAPI`` integration: handle ``Depends(Provide[...])``. - Update ``FastAPI`` example. +- Remove a typo from the ``Flask`` tutorial. 4.4.0 ----- diff --git a/docs/tutorials/flask.rst b/docs/tutorials/flask.rst index 5034d787..f22b6a2a 100644 --- a/docs/tutorials/flask.rst +++ b/docs/tutorials/flask.rst @@ -708,7 +708,6 @@ Edit ``views.py``: .. code-block:: python :emphasize-lines: 4,6-7,10-11,15 - :emphasize-lines: 4,6-7,10-11,15 """Views module.""" From d581a28b6e5457c8c35711d0874be40e0cdd70b3 Mon Sep 17 00:00:00 2001 From: Roman Mogylatov Date: Tue, 17 Nov 2020 23:58:44 -0500 Subject: [PATCH 4/4] Bump version to 4.4.1 --- docs/main/changelog.rst | 4 ++-- src/dependency_injector/__init__.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/main/changelog.rst b/docs/main/changelog.rst index 8a44cf1b..c74a981d 100644 --- a/docs/main/changelog.rst +++ b/docs/main/changelog.rst @@ -7,8 +7,8 @@ that were made in every particular version. From version 0.7.6 *Dependency Injector* framework strictly follows `Semantic versioning`_ -Develop -------- +4.4.1 +----- - Improve ``FastAPI`` integration: handle ``Depends(Provide[...])``. - Update ``FastAPI`` example. - Remove a typo from the ``Flask`` tutorial. diff --git a/src/dependency_injector/__init__.py b/src/dependency_injector/__init__.py index 78668b04..eb7c076c 100644 --- a/src/dependency_injector/__init__.py +++ b/src/dependency_injector/__init__.py @@ -1,6 +1,6 @@ """Top-level package.""" -__version__ = '4.4.0' +__version__ = '4.4.1' """Version number. :type: str