FastAPI + Abhängigkeitsinjektor





Hallo,



ich habe eine neue Version von Dependency Injector 4.4 veröffentlicht. Sie können den Abhängigkeitsinjektor mit FastAPI verwenden . In diesem Beitrag werde ich Ihnen zeigen, wie es funktioniert.



Die Hauptaufgabe der Integration besteht darin, sich mit der DependsFastAPI- Direktive mit Markern Provideund dem ProviderAbhängigkeitsinjektor anzufreunden.



Vor DI 4.4 hat es nicht sofort funktioniert. FastAPI verwendet Typisierung und Pydantic für die Eingabe- und Antwortvalidierung. Abhängigkeitsinjektormarker verwirrten ihn.



Die Lösung kam nach Prüfung der Interna von FastAPI. Ich musste einige Änderungen am Verkabelungsmodul des Dependency Injector vornehmen. Die Direktive arbeitet Dependsjetzt mit Markern Provideund Provider.



Beispiel



Erstellen Sie eine Datei fastapi_di_example.pyund fügen Sie die folgenden Zeilen ein:



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


Installieren Sie die Abhängigkeiten, um das Beispiel auszuführen:



pip install fastapi dependency-injector uvicorn


und laufen lassen uvicorn:



uvicorn fastapi_di_example:app --reload


Das Terminal sollte Folgendes anzeigen:



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.


http://127.0.0.1:8000sollte aber zurückkehren:



{
    "result": "Ok"
}




Wie teste ich?



Erstellen Sie eine Datei daneben tests.pyund fügen Sie die folgenden Zeilen ein:



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


Installieren Sie die Abhängigkeiten, um die Tests auszuführen:



pip install pytest pytest-asyncio httpx


und laufen lassen pytest:



pytest tests.py


Das Terminal sollte Folgendes anzeigen:



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


Was gibt Integration?



FastAPI ist ein cooles API-Framework. Der grundlegende Abhängigkeitsinjektionsmechanismus ist darin integriert.



Diese Integration verbessert die Abhängigkeitsinjektion in FastAPI. Sie können damit Anbieter, Überschreibungen, Konfigurationen und Ressourcen des Abhängigkeitsinjektors verwenden.



Was weiter?






All Articles