2025-06-13 12:22:11 +00:00

108 lines
3.1 KiB
Python

import uvicorn
import asyncio
import logging
import sys
from datetime import datetime
from fastapi import FastAPI, Depends, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from sqlalchemy.orm import Session
from app.api.v1.api import api_router
from app.core.config import settings
from app.db.session import get_db
from app.core.background_tasks import task_manager
# Configure logging
logging.basicConfig(
level=logging.DEBUG if settings.DEBUG else logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
handlers=[logging.StreamHandler(sys.stdout)]
)
logger = logging.getLogger(__name__)
app = FastAPI(
title=settings.PROJECT_NAME,
description=settings.PROJECT_DESCRIPTION,
version=settings.VERSION,
openapi_url="/openapi.json",
docs_url="/docs",
redoc_url="/redoc",
)
# Set up CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=settings.BACKEND_CORS_ORIGINS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Global exception handler
@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
logger.error(f"Unhandled exception: {str(exc)}", exc_info=True)
return JSONResponse(
status_code=500,
content={"detail": "Internal server error", "message": str(exc) if settings.DEBUG else None},
)
# Include API router
app.include_router(api_router, prefix=settings.API_V1_STR)
# Root endpoint
@app.get("/")
async def root():
return {
"name": settings.PROJECT_NAME,
"version": settings.VERSION,
"documentation": "/docs",
"health": "/health"
}
# Health check endpoint
@app.get("/health", tags=["health"])
async def health_check(db: Session = Depends(get_db)):
# Check if database is available
try:
# Execute a simple query
db.execute("SELECT 1")
db_status = "connected"
except Exception as e:
db_status = f"error: {str(e)}"
logger.error(f"Database health check failed: {str(e)}")
return {
"status": "ok",
"version": settings.VERSION,
"timestamp": datetime.utcnow().isoformat(),
"database": db_status,
"environment": "production" if not settings.DEBUG else "development",
}
# Startup event
@app.on_event("startup")
async def startup_event():
logger.info("Application startup initiated")
try:
# Start background tasks
asyncio.create_task(task_manager.start())
logger.info("Background tasks started successfully")
except Exception as e:
logger.error(f"Error starting background tasks: {str(e)}", exc_info=True)
# Shutdown event
@app.on_event("shutdown")
async def shutdown_event():
logger.info("Application shutdown initiated")
try:
# Stop background tasks
task_manager.stop()
logger.info("Background tasks stopped successfully")
except Exception as e:
logger.error(f"Error stopping background tasks: {str(e)}", exc_info=True)
if __name__ == "__main__":
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)