| import os |
| from contextlib import asynccontextmanager |
| from fastapi import FastAPI |
| from fastapi.staticfiles import StaticFiles |
| from fastapi.responses import FileResponse, JSONResponse |
| from fastapi.middleware.cors import CORSMiddleware |
| from fastapi.middleware.gzip import GZipMiddleware |
|
|
| from backend.database import init_db |
|
|
|
|
| @asynccontextmanager |
| async def lifespan(app: FastAPI): |
| init_db() |
| yield |
|
|
|
|
| app = FastAPI( |
| title="Compost API", |
| description="Unified AI Tool Integration Platform", |
| version="1.0.0", |
| docs_url="/api/docs", |
| redoc_url="/api/redoc", |
| lifespan=lifespan |
| ) |
|
|
| app.add_middleware( |
| CORSMiddleware, |
| allow_origins=["*"], |
| allow_credentials=True, |
| allow_methods=["*"], |
| allow_headers=["*"], |
| ) |
| app.add_middleware(GZipMiddleware, minimum_size=1000) |
|
|
| from backend.routers import auth, apps, tools, connections, apikeys, analytics, playground, settings, mcp, auth_configs |
|
|
| app.include_router(auth.router, prefix="/api/auth", tags=["auth"]) |
| app.include_router(apps.router, prefix="/api/apps", tags=["apps"]) |
| app.include_router(tools.router, prefix="/api/tools", tags=["tools"]) |
| app.include_router(connections.router, prefix="/api/connections", tags=["connections"]) |
| app.include_router(apikeys.router, prefix="/api/apikeys", tags=["apikeys"]) |
| app.include_router(analytics.router, prefix="/api/analytics", tags=["analytics"]) |
| app.include_router(playground.router, prefix="/api/playground", tags=["playground"]) |
| app.include_router(settings.router, prefix="/api/settings", tags=["settings"]) |
| app.include_router(mcp.router, prefix="/mcp", tags=["mcp"]) |
| app.include_router(auth_configs.router, prefix="/api/auth-configs", tags=["auth-configs"]) |
|
|
| @app.get("/health") |
| async def health(): |
| return {"status": "healthy", "version": "1.0.0"} |
|
|
|
|
| STATIC_DIR = os.path.join(os.path.dirname(__file__), "static") |
|
|
| if os.path.exists(STATIC_DIR): |
| app.mount("/_next", StaticFiles(directory=f"{STATIC_DIR}/_next"), name="next-assets") |
|
|
| @app.get("/{full_path:path}") |
| async def serve_spa(full_path: str): |
| if full_path.startswith("api/") or full_path.startswith("mcp/") or full_path == "health": |
| return JSONResponse({"detail": "Not found"}, status_code=404) |
| static_file = os.path.join(STATIC_DIR, full_path) |
| if os.path.isfile(static_file): |
| return FileResponse(static_file) |
| return FileResponse(os.path.join(STATIC_DIR, "index.html")) |
|
|
| @app.get("/") |
| async def root(): |
| return FileResponse(os.path.join(STATIC_DIR, "index.html")) |