"""Fractafrag API — Main application entrypoint.""" from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from app.database import engine from app.redis import close_redis from app.routers import auth, shaders, feed, votes, generate, desires, users, payments, mcp_keys, health @asynccontextmanager async def lifespan(app: FastAPI): """Application startup and shutdown lifecycle.""" # Startup yield # Shutdown await engine.dispose() await close_redis() app = FastAPI( title="Fractafrag API", description="GLSL shader platform — browse, create, generate, and share real-time GPU visuals", version="0.1.0", lifespan=lifespan, docs_url="/api/docs", redoc_url="/api/redoc", openapi_url="/api/openapi.json", ) # CORS — permissive in dev, lock down in production app.add_middleware( CORSMiddleware, allow_origins=["*"], # TODO: restrict in production allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # ── Mount Routers ───────────────────────────────────────── app.include_router(health.router) app.include_router(auth.router, prefix="/api/v1/auth", tags=["auth"]) app.include_router(shaders.router, prefix="/api/v1/shaders", tags=["shaders"]) app.include_router(feed.router, prefix="/api/v1/feed", tags=["feed"]) app.include_router(votes.router, prefix="/api/v1", tags=["votes"]) app.include_router(generate.router, prefix="/api/v1/generate", tags=["generate"]) app.include_router(desires.router, prefix="/api/v1/desires", tags=["desires"]) app.include_router(users.router, prefix="/api/v1", tags=["users"]) app.include_router(payments.router, prefix="/api/v1/payments", tags=["payments"]) app.include_router(mcp_keys.router, prefix="/api/v1/me/api-keys", tags=["api-keys"])