Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 5 additions & 11 deletions src/app/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,25 @@
from dishka.integrations.fastapi import setup_dishka
from fastapi import FastAPI

from app.presentation.http.controllers.root_router import create_root_router
from app.setup.app_factory import configure_app, create_app, create_async_ioc_container
from app.setup.app_factory import create_ioc_container, create_web_app
from app.setup.config.logs import configure_logging
from app.setup.config.settings import AppSettings, load_settings
from app.setup.ioc.provider_registry import get_providers


def make_app(
*di_providers: Provider,
settings: AppSettings | None = None,
) -> FastAPI:
"""Pass providers to override existing ones for testing."""
if settings is None:
configure_logging()
settings = load_settings()

configure_logging(level=settings.logs.level)

app: FastAPI = create_app()
configure_app(app=app, root_router=create_root_router())

async_ioc_container = create_async_ioc_container(
providers=(*get_providers(), *di_providers),
settings=settings,
)
setup_dishka(container=async_ioc_container, app=app)
app: FastAPI = create_web_app()
container = create_ioc_container(settings, *di_providers)
setup_dishka(container, app)

return app

Expand Down
49 changes: 23 additions & 26 deletions src/app/setup/app_factory.py
Original file line number Diff line number Diff line change
@@ -1,48 +1,45 @@
from collections.abc import AsyncIterator, Iterable
from collections.abc import AsyncIterator
from contextlib import asynccontextmanager

from dishka import AsyncContainer, Provider, make_async_container
from fastapi import APIRouter, FastAPI
from fastapi import FastAPI
from fastapi.responses import ORJSONResponse

from app.infrastructure.persistence_sqla.mappings.all import map_tables
from app.presentation.http.auth.asgi_middleware import (
ASGIAuthMiddleware,
)
from app.presentation.http.controllers.root_router import create_root_router
from app.setup.config.settings import AppSettings
from app.setup.ioc.provider_registry import get_providers


def create_app() -> FastAPI:
return FastAPI(
def create_ioc_container(
settings: AppSettings,
*di_providers: Provider,
) -> AsyncContainer:
return make_async_container(
*get_providers(),
*di_providers,
context={AppSettings: settings},
)


def create_web_app() -> FastAPI:
app = FastAPI(
lifespan=lifespan,
default_response_class=ORJSONResponse,
)
# https://github.com/encode/starlette/discussions/2451
app.add_middleware(ASGIAuthMiddleware)
# Good place to register global exception handlers
app.include_router(create_root_router())
return app


@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncIterator[None]:
map_tables()
yield None
await app.state.dishka_container.close()
# https://dishka.readthedocs.io/en/stable/integrations/fastapi.html


def configure_app(
app: FastAPI,
root_router: APIRouter,
) -> None:
app.include_router(root_router)
app.add_middleware(ASGIAuthMiddleware)
# https://github.com/encode/starlette/discussions/2451

# Good place to register global exception handlers


def create_async_ioc_container(
providers: Iterable[Provider],
settings: AppSettings,
) -> AsyncContainer:
return make_async_container(
*providers,
context={AppSettings: settings},
)
await app.state.dishka_container.close()