FastAPI + Injector Ketergantungan





Hai,



Saya telah merilis versi baru dari Dependency Injector 4.4. Ini memungkinkan Anda untuk menggunakan Dependency Injector dengan FastAPI . Dalam posting ini saya akan menunjukkan cara kerjanya.



Tugas utama integrasi adalah berteman dengan direktif DependsFastAPI dengan marker Providedan ProviderDependency Injector.



Itu tidak berhasil di luar kotak sebelum DI 4.4. FastAPI menggunakan pengetikan dan Pydantic untuk validasi input dan respons. Penanda Ketergantungan Injector membuatnya bingung.



Solusinya datang setelah memeriksa internal FastAPI. Saya harus membuat beberapa perubahan pada modul kabel dari Dependency Injector. Direktif Dependssekarang bekerja dengan penanda Providedan Provider.



Contoh



Buat file fastapi_di_example.pydan letakkan baris berikut di dalamnya:



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


Untuk menjalankan contoh, instal dependensi:



pip install fastapi dependency-injector uvicorn


dan lari uvicorn:



uvicorn fastapi_di_example:app --reload


Terminal akan menampilkan sesuatu seperti:



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.


tetapi http://127.0.0.1:8000harus mengembalikan:



{
    "result": "Ok"
}




Bagaimana cara mengujinya?



Buat file di sebelahnya tests.pydan letakkan baris berikut di dalamnya:



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


Untuk menjalankan pengujian, instal dependensi:



pip install pytest pytest-asyncio httpx


dan lari pytest:



pytest tests.py


Terminal harus menampilkan:



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


Apa yang diberikan integrasi?



FastAPI adalah kerangka kerja pembuatan API yang keren. Mekanisme injeksi ketergantungan dasar dibangun di dalamnya.



Integrasi ini meningkatkan pengalaman injeksi ketergantungan FastAPI. Ini memungkinkan Anda untuk menggunakan penyedia, penggantian, konfigurasi, dan sumber daya Ketergantungan Injector di dalamnya.



Apa berikutnya?






All Articles