FastAPI +依存関係インジェクター





こんにちは、Dependency Injector4.4の



新しいバージョンをリリースしましたこれにより、FastAPIでDependencyInjectorを使用できますこの投稿では、それがどのように機能するかを紹介します。



統合の主なタスクは、DependsマーカーProvideProvider依存関係インジェクター備えたFastAPIディレクティブ友達になることです。



DI 4.4より前は、そのままでは機能しませんでした。FastAPIは、入力と応答の検証にタイピングとPydanticを使用します。依存性インジェクターマーカーは彼を困惑させた。



解決策は、FastAPIの内部を調べた後に生まれました。DependencyInjectorの配線モジュールにいくつかの変更を加える必要がありました。ディレクティブDependsがマーカーProvideとで機能するようになりましたProvider





ファイルfastapi_di_example.py作成し、その中に次の行を入力します。



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


例を実行するには、依存関係をインストールします。



pip install fastapi dependency-injector uvicorn


実行しますuvicorn



uvicorn fastapi_di_example:app --reload


ターミナルは次のように表示されます。



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:8000戻る必要あります:



{
    "result": "Ok"
}




テストする方法は?



その横tests.pyファイルを作成し、次の行を入力します。



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


テストを実行するには、依存関係をインストールします。



pip install pytest pytest-asyncio httpx


実行しますpytest



pytest tests.py


端末に次のように表示されます。



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


統合は何をもたらしますか?



FastAPIは、クールなAPI構築フレームワークです。基本的な依存関係注入メカニズムが組み込まれています。



この統合により、FastAPIでの依存関係の挿入が改善されます。これにより、依存関係インジェクターのプロバイダー、オーバーライド、構成、およびリソースを使用できます。



次は何ですか?






All Articles