from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse import logging from app.config import settings from app.routers import auth, chatbots, documents, chat, marketplace, billing, models # Configure logging logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", ) logger = logging.getLogger(__name__) # BUG-13 FIX: Replace deprecated @app.on_event("startup") with lifespan @asynccontextmanager async def lifespan(app: FastAPI): # Startup logger.info("Contexta API starting up...") logger.info(f"Environment: {settings.app_env}") logger.info(f"Allowed origins: {settings.allowed_origins_list}") yield # Shutdown logger.info("Contexta API shutting down...") # ── App ────────────────────────────────────────────────────────────────────────── app = FastAPI( title="Contexta API", description="AI Chatbot Platform - Create, deploy and share custom AI chatbots powered by your data", version="1.0.0", docs_url="/docs", redoc_url="/redoc", lifespan=lifespan, ) # ── Middleware ───────────────────────────────────────────────────────────────── app.add_middleware( CORSMiddleware, allow_origins=settings.allowed_origins_list, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # ── Routers ──────────────────────────────────────────────────────────────────── app.include_router(auth.router, prefix="/api/v1") app.include_router(chatbots.router, prefix="/api/v1") app.include_router(documents.router, prefix="/api/v1") app.include_router(chat.router, prefix="/api/v1") app.include_router(marketplace.router, prefix="/api/v1") app.include_router(billing.router, prefix="/api/v1") app.include_router(models.router, prefix="/api/v1") # ── Health & Info ────────────────────────────────────────────────────────────── @app.get("/") async def root(): return { "name": "Contexta API", "version": "1.0.0", "status": "running", "docs": "/docs", } @app.get("/health") async def health(): return {"status": "healthy", "environment": settings.app_env} # ── Sentry ───────────────────────────────────────────────────────────────────── if settings.sentry_dsn: import sentry_sdk sentry_sdk.init(dsn=settings.sentry_dsn, traces_sample_rate=0.1) logger.info("Sentry initialized") if __name__ == "__main__": import uvicorn uvicorn.run("app.main:app", host="0.0.0.0", port=8000, reload=True)