""" Galaxis-Po Backend API """ import logging from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from app.api import ( auth_router, admin_router, portfolio_router, strategy_router, market_router, backtest_router, snapshot_router, data_explorer_router, signal_router, ) # Configure logging logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", ) logger = logging.getLogger(__name__) def _seed_admin_user() -> None: """Create admin user from env vars if not exists.""" from app.core.config import get_settings from app.core.database import SessionLocal from app.core.security import get_password_hash from app.models.user import User settings = get_settings() if not settings.admin_username or not settings.admin_password: logger.info("ADMIN_USERNAME/ADMIN_PASSWORD not set, skipping admin seed") return db = SessionLocal() try: existing = db.query(User).filter(User.username == settings.admin_username).first() if existing: logger.info(f"Admin user '{settings.admin_username}' already exists") return user = User( username=settings.admin_username, email=settings.admin_email or f"{settings.admin_username}@local", hashed_password=get_password_hash(settings.admin_password), ) db.add(user) db.commit() logger.info(f"Admin user '{settings.admin_username}' created") except Exception as e: db.rollback() logger.error(f"Failed to seed admin user: {e}") finally: db.close() @asynccontextmanager async def lifespan(app: FastAPI): """Application lifespan manager.""" # Startup logger.info("Starting Galaxis-Po API...") # Seed admin user _seed_admin_user() # Start scheduler (import here to avoid circular imports) try: from jobs.scheduler import start_scheduler start_scheduler() logger.info("Scheduler started") except Exception as e: logger.warning(f"Failed to start scheduler: {e}") yield # Shutdown logger.info("Shutting down Galaxis-Po API...") try: from jobs.scheduler import stop_scheduler stop_scheduler() logger.info("Scheduler stopped") except Exception as e: logger.warning(f"Failed to stop scheduler: {e}") app = FastAPI( title="Galaxis-Po API", description="Quant Portfolio Management API", version="0.1.0", lifespan=lifespan, ) from app.core.config import get_settings _settings = get_settings() app.add_middleware( CORSMiddleware, allow_origins=[origin.strip() for origin in _settings.cors_origins.split(",") if origin.strip()], allow_credentials=True, allow_methods=["GET", "POST", "PUT", "DELETE"], allow_headers=["*"], ) # Include routers app.include_router(auth_router) app.include_router(admin_router) app.include_router(portfolio_router) app.include_router(strategy_router) app.include_router(market_router) app.include_router(backtest_router) app.include_router(snapshot_router) app.include_router(data_explorer_router) app.include_router(signal_router) @app.get("/health") async def health_check(): return {"status": "healthy"}