Injecteur de dépendances FastAPI +





Salut,



j'ai publié une nouvelle version de Dependency Injector 4.4. Il vous permet d'utiliser Dependency Injector avec FastAPI . Dans cet article, je vais vous montrer comment cela fonctionne.



La tâche principale de l'intégration est de se Dependslier d' amitié avec la directive FastAPI avec des marqueurs Provideet l' Providerinjecteur de dépendances.



Cela ne fonctionnait pas directement avant DI 4.4. FastAPI utilise le typage et Pydantic pour la validation des entrées et des réponses. Les marqueurs d'injecteur de dépendance l'ont intrigué.



La solution est venue après avoir examiné les composants internes de FastAPI. J'ai dû apporter quelques modifications au module de câblage de l'injecteur de dépendance. La directive Dependsfonctionne désormais avec les marqueurs Provideet Provider.



Exemple



Créez un fichier fastapi_di_example.pyet mettez-y les lignes suivantes:



import sys

from fastapi import FastAPI, Depends
from dependency_injector import containers, providers
from dependency_injector.wiring import inject, Provide


class Service:
    async def process(self) -> str:
        return 'Ok'


class Container(containers.DeclarativeContainer):

    service = providers.Factory(Service)


app = FastAPI()


@app.api_route('/')
@inject
async def index(service: Service = Depends(Provide[Container.service])):
    result = await service.process()
    return {'result': result}


container = Container()
container.wire(modules=[sys.modules[__name__]])


Pour exécuter l'exemple, installez les dépendances:



pip install fastapi dependency-injector uvicorn


et exécutez uvicorn:



uvicorn fastapi_di_example:app --reload


Le terminal devrait afficher quelque chose comme:



INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [11910] using watchgod
INFO:     Started server process [11912]
INFO:     Waiting for application startup.
INFO:     Application startup complete.


mais http://127.0.0.1:8000devrait revenir:



{
    "result": "Ok"
}




Comment tester?



Créez un fichier à côté tests.pyet mettez-y les lignes suivantes:



from unittest import mock

import pytest
from httpx import AsyncClient

from fastapi_di_example import app, container, Service


@pytest.fixture
def client(event_loop):
    client = AsyncClient(app=app, base_url='http://test')
    yield client
    event_loop.run_until_complete(client.aclose())


@pytest.mark.asyncio
async def test_index(client):
    service_mock = mock.AsyncMock(spec=Service)
    service_mock.process.return_value = 'Foo'

    with container.service.override(service_mock):
        response = await client.get('/')

    assert response.status_code == 200
    assert response.json() == {'result': 'Foo'}


Pour exécuter les tests, installez les dépendances:



pip install pytest pytest-asyncio httpx


et exécutez pytest:



pytest tests.py


Le terminal doit afficher:



======= test session starts =======
platform darwin -- Python 3.8.3, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
rootdir: ...
plugins: asyncio-0.14.0
collected 1 item

tests.py .                                                      [100%]

======= 1 passed in 0.17s =======


Que donne l'intégration?



FastAPI est un framework de création d'API sympa. Le mécanisme d'injection de dépendances de base y est intégré.



Cette intégration améliore l'expérience d'injection de dépendances FastAPI. Il vous permet d'utiliser les fournisseurs, les remplacements, la configuration et les ressources de l'injecteur de dépendances.



Et après?






All Articles