import os import time from contextlib import asynccontextmanager from pathlib import Path from dotenv import load_dotenv from fastapi import FastAPI from sqlalchemy import text from starlette.middleware.sessions import SessionMiddleware from app.routes import router as api_router from app.utils.cors import setup_cors from app.utils.create_tables import init_db from app.utils.db import get_engine, init_db_engine from app.utils.logger_cfg import logger load_dotenv(Path(__file__).resolve().parent.parent / ".env") init_db_engine() app_start_time = time.perf_counter() logger.debug("App start timestamp recorded") @asynccontextmanager async def lifespan(app: FastAPI): logger.info("Application startup initiated") engine = get_engine() try: async with engine.begin() as conn: logger.debug("Executing test query: SELECT 1") db_status = await conn.scalar(text("SELECT 1")) logger.info("Database connection successful: {}", db_status) logger.debug("Starting database table initialization") await init_db() logger.info("Database initialization completed") except Exception: logger.exception("Database startup failed") raise elapsed = time.perf_counter() - app_start_time app.state.startup_elapsed = elapsed app.state.startup_completed = True logger.success( "Application startup completed in {:.2f} ms ({:.6f} s)", elapsed * 1000, elapsed, ) yield logger.info("Application shutdown initiated") try: engine = get_engine() await engine.dispose() logger.info("Database engine disposed successfully") except Exception: logger.exception("Error during shutdown") app = FastAPI(lifespan=lifespan) app.add_middleware( SessionMiddleware, secret_key=os.getenv("SESSION_SECRET_KEY", "dev-secret"), same_site="lax", https_only=False, ) setup_cors(app) app.include_router(api_router, prefix="/api")