Spaces:
Running
Running
| """FastAPI application entry point. | |
| [Task]: T047 | |
| [From]: specs/001-user-auth/plan.md | |
| """ | |
| import logging | |
| from contextlib import asynccontextmanager | |
| from fastapi import FastAPI, HTTPException | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.responses import JSONResponse | |
| from datetime import datetime | |
| import time | |
| from core.database import init_db, engine | |
| from core.config import get_settings | |
| from api.auth import router as auth_router | |
| from api.tasks import router as tasks_router | |
| from api.chat import router as chat_router | |
| from core.logging import setup_logging, get_logger | |
| settings = get_settings() | |
| # Setup structured logging | |
| setup_logging() | |
| logger = get_logger(__name__) | |
| async def lifespan(app: FastAPI): | |
| """Application lifespan manager. | |
| Handles startup and shutdown events with graceful connection cleanup. | |
| """ | |
| # Startup | |
| logger.info("Starting up application...") | |
| init_db() | |
| logger.info("Database initialized") | |
| # Track background tasks for graceful shutdown | |
| background_tasks = set() | |
| yield | |
| # Shutdown - Graceful shutdown handler | |
| logger.info("Shutting down application...") | |
| # Close database connections | |
| try: | |
| logger.info("Closing database connections...") | |
| await engine.dispose() | |
| logger.info("Database connections closed") | |
| except Exception as e: | |
| logger.error(f"Error closing database: {e}") | |
| # Wait for background tasks to complete (with timeout) | |
| if background_tasks: | |
| logger.info(f"Waiting for {len(background_tasks)} background tasks to complete...") | |
| try: | |
| # Wait up to 10 seconds for tasks to complete | |
| import asyncio | |
| await asyncio.wait_for(asyncio.gather(*background_tasks, return_exceptions=True), timeout=10.0) | |
| logger.info("All background tasks completed") | |
| except asyncio.TimeoutError: | |
| logger.warning("Background tasks did not complete in time, forcing shutdown...") | |
| logger.info("Application shutdown complete") | |
| # Create FastAPI application | |
| app = FastAPI( | |
| title="Todo List API", | |
| description="REST API for managing tasks with JWT authentication", | |
| version="1.0.0", | |
| lifespan=lifespan, | |
| ) | |
| # Add CORS middleware | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=[settings.frontend_url], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # Include routers | |
| app.include_router(auth_router) # Authentication endpoints | |
| app.include_router(tasks_router) # Task management endpoints | |
| app.include_router(chat_router) # AI chat endpoints (Phase III) | |
| async def root(): | |
| """Root endpoint.""" | |
| return { | |
| "message": "Todo List API", | |
| "status": "running", | |
| "version": "2.0.0", | |
| "authentication": "JWT", | |
| "features": { | |
| "task_management": "REST API for CRUD operations", | |
| "ai_chatbot": "Natural language task creation and listing" | |
| } | |
| } | |
| async def health_check(): | |
| """Health check endpoint. | |
| Verifies database connectivity and application status. | |
| Returns 503 if database is unavailable. | |
| [Task]: T048 | |
| [From]: specs/001-user-auth/plan.md | |
| """ | |
| from sqlmodel import select | |
| from models.user import User | |
| from sqlmodel import Session | |
| # Try to get database session | |
| try: | |
| # Create a simple query to test database connection | |
| with Session(engine) as session: | |
| # Execute a simple query (doesn't matter if it returns data) | |
| session.exec(select(User).limit(1)) | |
| return {"status": "healthy", "database": "connected", "timestamp": datetime.utcnow().isoformat()} | |
| except Exception as e: | |
| logger.error(f"Health check failed: {e}") | |
| raise HTTPException( | |
| status_code=503, | |
| detail="Service unavailable - database connection failed" | |
| ) | |
| async def metrics(): | |
| """Metrics endpoint for monitoring. | |
| Returns basic application metrics for Kubernetes health probes. | |
| """ | |
| return { | |
| "status": "running", | |
| "timestamp": datetime.utcnow().isoformat(), | |
| "uptime_seconds": time.time(), | |
| "version": "1.0.0", | |
| "database": "connected" # Simplified - in production would check actual DB status | |
| } | |
| # Global exception handler | |
| async def http_exception_handler(request, exc): | |
| """Global HTTP exception handler. | |
| Returns consistent error format for all HTTP exceptions. | |
| [Task]: T046 | |
| [From]: specs/001-user-auth/research.md | |
| """ | |
| return JSONResponse( | |
| status_code=exc.status_code, | |
| content={ | |
| "error": { | |
| "status_code": exc.status_code, | |
| "detail": exc.detail | |
| } | |
| } | |
| ) | |