import logging import os import uvicorn from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import RedirectResponse from app.api.routers.chat import chat_router from app.api.routers.user import user_router from app.api.routers.transaction import transaction_router from app.settings import init_settings from fastapi.staticfiles import StaticFiles from alembic.config import Config from alembic import command from app.engine.postgresdb import postgresdb from config.index import config logger = logging.getLogger("uvicorn") def run_migrations(connection, cfg): cfg.attributes["connection"] = connection command.upgrade(cfg, "head") async def run_async_migrations(): logger.info("Running migrations...") async_engine = postgresdb.get_engine() async with async_engine.begin() as conn: await conn.run_sync(run_migrations, Config("alembic.ini")) logger.info("Finished running migrations") @asynccontextmanager async def lifespan(app_: FastAPI): yield if postgresdb.get_engine() is not None: await postgresdb.close() init_settings() # init_observability() def init_app(): app = FastAPI(lifespan=lifespan) if config.ENVIRONMENT == "dev": logger.warning("Running in development mode - allowing CORS for all origins") app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) if os.path.exists("data"): app.mount("/api/data", StaticFiles(directory="data"), name="static") app.include_router(chat_router, prefix="/api/chat") app.include_router(user_router) app.include_router(transaction_router) return app app = init_app() if __name__ == "__main__": # Redirect to documentation page when accessing base URL @app.get("/") async def redirect_to_docs(): return RedirectResponse(url="/docs") uvicorn.run(app="main:app", host=config.APP_HOST, port=config.APP_PORT, reload=(config.ENVIRONMENT == "dev"))