34 lines
960 B
Python
34 lines
960 B
Python
|
|
"""Sagaphone FastAPI entrypoint.
|
||
|
|
|
||
|
|
Routes are added as features land (see ../SPEC.md and ../spec/*.md).
|
||
|
|
This currently only wires up app creation, logging, and a health check
|
||
|
|
so the scaffold is runnable end to end.
|
||
|
|
"""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import logging
|
||
|
|
|
||
|
|
from fastapi import FastAPI, Request
|
||
|
|
from fastapi.responses import JSONResponse
|
||
|
|
|
||
|
|
from app.errors import AppError
|
||
|
|
from app.logging_config import configure_logging
|
||
|
|
|
||
|
|
configure_logging()
|
||
|
|
logger = logging.getLogger(__name__)
|
||
|
|
|
||
|
|
app = FastAPI(title="Sagaphone", version="0.1.0")
|
||
|
|
|
||
|
|
|
||
|
|
@app.exception_handler(AppError)
|
||
|
|
async def app_error_handler(_request: Request, exc: AppError) -> JSONResponse:
|
||
|
|
"""Edge-catch: translate AppError subclasses into clean HTTP responses."""
|
||
|
|
logger.error("request failed: %s", exc.message)
|
||
|
|
return JSONResponse(status_code=exc.status_code, content={"error": exc.message})
|
||
|
|
|
||
|
|
|
||
|
|
@app.get("/health")
|
||
|
|
async def health() -> dict[str, str]:
|
||
|
|
return {"status": "ok"}
|