import logging from fastapi import FastAPI from fastapi import HTTPException from fastapi.exceptions import RequestValidationError from fastapi.encoders import jsonable_encoder from fastapi.responses import JSONResponse from starlette import status from starlette.requests import Request from app.api.auth import router as auth_router from app.api.permissions import router as permissions_router from app.api.roles import router as roles_router from app.api.users import router as users_router from app.db.database import SessionLocal from app.db.health import check_database from app.rbac.seed import seed_rbac app = FastAPI( title="Hermes API", version="0.1.0", description="Backend von Olympus", ) app.include_router(auth_router) app.include_router(users_router) app.include_router(roles_router) app.include_router(permissions_router) logger = logging.getLogger(__name__) @app.on_event("startup") def startup_seed_rbac(): db = SessionLocal() try: seed_rbac(db) finally: db.close() @app.exception_handler(HTTPException) async def http_exception_handler(request: Request, exc: HTTPException): logger.warning( "http_exception", extra={ "path": request.url.path, "method": request.method, "status_code": exc.status_code, }, ) return JSONResponse( status_code=exc.status_code, content={"detail": exc.detail}, headers=exc.headers, ) @app.exception_handler(RequestValidationError) async def validation_exception_handler(request: Request, exc: RequestValidationError): logger.warning( "validation_exception", extra={"path": request.url.path, "method": request.method}, ) return JSONResponse( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, content={"detail": jsonable_encoder(exc.errors())}, ) @app.exception_handler(Exception) async def unhandled_exception_handler(request: Request, exc: Exception): logger.exception( "unhandled_exception", extra={"path": request.url.path, "method": request.method}, ) return JSONResponse( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={"detail": "Interner Serverfehler"}, ) @app.get("/") def root(): return { "service": "Hermes", "status": "running", } @app.get("/health") def health(): return { "status": "healthy", "database": check_database(), }