Model/backend/app/main.py
Khalim Conn-Kowlessar b62901a9de The distributor coexists with both table stacks and mounts at /v1/modelling 🟪
DB access via parameterised SQL, not the infrastructure SQLModel mirrors:
importing those alongside the legacy backend.app.db.models mirrors of the
same tables double-registers them in the shared metadata and crashes the
app at import. Contained to the modelling package until the DDD cut-over.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 12:15:31 +00:00

74 lines
2.7 KiB
Python

import logging
import os
from fastapi.responses import JSONResponse
from fastapi import FastAPI, Depends, Request, status
from fastapi.exceptions import RequestValidationError
from fastapi.encoders import jsonable_encoder
from starlette.exceptions import HTTPException as StarletteHTTPException
from mangum import Mangum
from backend.app.portfolio import router as portfolio_router
from backend.app.whlg import router as whlg_router
from backend.app.plan import router as plan_router
from backend.app.tasks import router as tasks_router
from backend.app.bulk_uploads import router as bulk_uploads_router
from backend.app.modelling import router as modelling_router
from backend.app.dependencies import validate_api_key
from backend.app.config import get_settings
logger = logging.getLogger("uvicorn.error")
logging.basicConfig(level=logging.INFO)
if get_settings().ENVIRONMENT == "local":
app = FastAPI()
else:
app = FastAPI(dependencies=[Depends(validate_api_key)])
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
logger.error(f"422 Validation Error at {request.url}")
logger.error(f"Body: {exc.body}")
logger.error(f"Validation Errors: {exc.errors()}")
return JSONResponse(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
content=jsonable_encoder({"detail": exc.errors(), "body": exc.body}),
)
@app.exception_handler(StarletteHTTPException)
async def http_exception_handler(request: Request, exc: StarletteHTTPException):
logger.warning(f"{exc.status_code} Error at {request.url} - Detail: {exc.detail}")
return JSONResponse(
status_code=exc.status_code,
content={"detail": exc.detail},
)
@app.middleware("http")
async def log_requests(request: Request, call_next):
logger.info(f"Incoming request: {request.method} {request.url}")
response = await call_next(request)
logger.info(f"Response status: {response.status_code}")
return response
@app.get("/health")
async def health():
sha = os.getenv("GITHUB_SHA", "unknown")
logger.info(f"Health check OK - deployed sha={sha}")
return {"status": "ok", "sha": sha}
app.include_router(tasks_router.router, prefix="/v1")
app.include_router(portfolio_router.router, prefix="/v1")
app.include_router(plan_router.router, prefix="/v1")
app.include_router(whlg_router.router, prefix="/v1")
app.include_router(bulk_uploads_router.router, prefix="/v1")
app.include_router(modelling_router.router, prefix="/v1")
if get_settings().ENVIRONMENT == "local":
from backend.app.local import router as local_router
app.include_router(local_router.router)
handler = Mangum(app)