c7e078d758
Replace the placeholder MUSICBRAINZ_USER_AGENT env var with
MUSICBRAINZ_OWNER_EMAIL. The User-Agent ("MCMA/<version> ( <contact> )")
is now composed from the fixed app name, the installed package version,
and the operator's contact email — falling back to the project URL when
no email is configured. Also use the same version for the FastAPI app.
58 lines
1.6 KiB
Python
58 lines
1.6 KiB
Python
"""FastAPI composition root: wiring, lifespan, middleware, routers."""
|
|
|
|
from collections.abc import AsyncIterator
|
|
from contextlib import asynccontextmanager
|
|
|
|
from fastapi import FastAPI, WebSocket
|
|
|
|
from app.api.errors import register_exception_handlers
|
|
from app.api.health import router as health_router
|
|
from app.api.middleware import CorrelationIdMiddleware
|
|
from app.api.rest import subsonic_router
|
|
from app.api.v1 import api_v1_router
|
|
from app.core.config import app_version, get_settings
|
|
from app.core.logging import configure_logging, get_logger
|
|
from app.infrastructure.cache import close_redis
|
|
from app.infrastructure.db import dispose_engine
|
|
|
|
log = get_logger(__name__)
|
|
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(_app: FastAPI) -> AsyncIterator[None]:
|
|
settings = get_settings()
|
|
log.info("startup", environment=settings.environment)
|
|
yield
|
|
log.info("shutdown")
|
|
await dispose_engine()
|
|
await close_redis()
|
|
|
|
|
|
def create_app() -> FastAPI:
|
|
settings = get_settings()
|
|
configure_logging(level=settings.log_level, json=settings.log_json)
|
|
|
|
app = FastAPI(
|
|
title="mcma-backend",
|
|
version=app_version(),
|
|
summary="Self-hosted, offline-first music service.",
|
|
lifespan=lifespan,
|
|
)
|
|
|
|
app.add_middleware(CorrelationIdMiddleware)
|
|
register_exception_handlers(app)
|
|
|
|
app.include_router(health_router)
|
|
app.include_router(api_v1_router)
|
|
app.include_router(subsonic_router, prefix="/rest")
|
|
|
|
@app.websocket("/ws")
|
|
async def ws_stub(websocket: WebSocket) -> None:
|
|
await websocket.accept()
|
|
await websocket.close(1001)
|
|
|
|
return app
|
|
|
|
|
|
app = create_app()
|