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
Depends
lier d' amitié avec la directive FastAPI avec des marqueurs Provide
et l' Provider
injecteur 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
Depends
fonctionne désormais avec les marqueurs Provide
et Provider
.
Exemple
Créez un fichier
fastapi_di_example.py
et 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:8000
devrait revenir:
{
"result": "Ok"
}
Comment tester?
Créez un fichier à côté
tests.py
et 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?
- DĂ©couvrez le Github du projet
- Consultez la documentation
- Voir un exemple FastAPI avec plusieurs modules