Inyector de dependencia FastAPI +





Hola,



he lanzado una nueva versión de Dependency Injector 4.4. Le permite utilizar Dependency Injector con FastAPI . En esta publicación te mostraré cómo funciona.



La tarea principal de la integración es hacerse amigo de la directiva DependsFastAPI con marcadores Providey el ProviderInyector de dependencias.



No funcionó de fábrica antes de DI 4.4. FastAPI usa escritura y Pydantic para la validación de entrada y respuesta. Los marcadores del inyector de dependencia lo desconcertaron.



La solución llegó después de examinar las partes internas de FastAPI. Tuve que realizar varios cambios en el módulo de cableado del inyector de dependencia. La directiva Dependsahora funciona con marcadores Providey Provider.



Ejemplo



Cree un archivo fastapi_di_example.pyy coloque las siguientes líneas en él:



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__]])


Para ejecutar el ejemplo, instale las dependencias:



pip install fastapi dependency-injector uvicorn


y ejecutar uvicorn:



uvicorn fastapi_di_example:app --reload


La terminal debería mostrar algo como:



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.


pero http://127.0.0.1:8000debería regresar:



{
    "result": "Ok"
}




¿Cómo probar?



Cree un archivo junto tests.pya él y coloque las siguientes líneas en él:



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'}


Para ejecutar las pruebas, instale las dependencias:



pip install pytest pytest-asyncio httpx


y ejecutar pytest:



pytest tests.py


La terminal debe mostrar:



======= 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 =======


¿Qué aporta la integración?



FastAPI es un marco de construcción de API genial. El mecanismo básico de inyección de dependencia está integrado en él.



Esta integración mejora la inyección de dependencia en FastAPI. Le permite usar proveedores, anulaciones, configuraciones y recursos del inyector de dependencia en él.



¿Que sigue?






All Articles