from fastapi import FastAPI, Request from fastapi.templating import Jinja2Templates from fastapi.staticfiles import StaticFiles from contextlib import asynccontextmanager from src.utils.logging_config import setup_logging from alembic.config import Config from alembic import command import os import logging @asynccontextmanager async def lifespan(app: FastAPI): # Startup setup_logging() logger = logging.getLogger(__name__) logger.info("--- Application Starting Up ---") logger.debug("--- TEST DEBUG LOG AT STARTUP ---") alembic_cfg = Config("alembic.ini") database_url = os.getenv("DATABASE_URL") if database_url: alembic_cfg.set_main_option("sqlalchemy.url", database_url) try: command.upgrade(alembic_cfg, "head") logger.info("Database migrations checked/applied.") except Exception as e: logger.error(f"Error running database migrations: {e}") else: logger.warning("DATABASE_URL not set, skipping migrations.") yield logger.info("--- Application Shutting Down ---") app = FastAPI(lifespan=lifespan) # Add middleware for request logging @app.middleware("http") async def log_requests(request: Request, call_next): logger = logging.getLogger("src.middleware") logger.info(f"Incoming Request: {request.method} {request.url.path}") try: response = await call_next(request) logger.info(f"Request Completed: {response.status_code}") return response except Exception as e: logger.error(f"Request Failed: {e}") raise app.mount("/static", StaticFiles(directory="../static"), name="static") templates = Jinja2Templates(directory="templates") from src.api import status, sync, setup, logs, metrics, activities app.include_router(status.router, prefix="/api") app.include_router(sync.router, prefix="/api") app.include_router(setup.router, prefix="/api") app.include_router(logs.router, prefix="/api") app.include_router(metrics.router, prefix="/api") app.include_router(activities.router, prefix="/api") @app.get("/") async def read_root(request: Request): return templates.TemplateResponse("index.html", {"request": request}) @app.get("/activities") async def activities_page(request: Request): return templates.TemplateResponse("activities.html", {"request": request}) @app.get("/setup") async def setup_page(request: Request): return templates.TemplateResponse("setup.html", {"request": request})