import logging from contextlib import asynccontextmanager import socketio from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from app.api.routes import auth, games, health, teams from app.config import get_settings from app.database.session import init_db from app.services import redis_client from app.utils.logging import setup_logging from app.websocket.connection_manager import ConnectionManager from app.websocket.handlers import register_handlers logger = logging.getLogger(f"{__name__}.main") @asynccontextmanager async def lifespan(app: FastAPI): """Startup and shutdown events""" settings = get_settings() # Startup logger.info("Starting Paper Dynasty Game Backend") setup_logging() # Initialize database await init_db() logger.info("Database initialized") # Initialize Redis try: redis_url = settings.redis_url await redis_client.connect(redis_url) logger.info(f"Redis initialized: {redis_url}") except Exception as e: logger.warning( f"Redis connection failed: {e}. Position rating caching will be unavailable." ) yield # Shutdown logger.info("Shutting down Paper Dynasty Game Backend") # Disconnect Redis if redis_client.is_connected: await redis_client.disconnect() logger.info("Redis disconnected") # Initialize FastAPI app app = FastAPI( title="Paper Dynasty Game Backend", description="Real-time baseball game engine for Paper Dynasty leagues", version="1.0.0", lifespan=lifespan, ) # CORS middleware settings = get_settings() app.add_middleware( CORSMiddleware, allow_origins=settings.cors_origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Initialize Socket.io sio = socketio.AsyncServer( async_mode="asgi", cors_allowed_origins=settings.cors_origins, logger=True, engineio_logger=False, ) # Create Socket.io ASGI app socket_app = socketio.ASGIApp(sio, app) # Initialize connection manager and register handlers connection_manager = ConnectionManager(sio) register_handlers(sio, connection_manager) # Configure game engine with connection manager for real-time event emission from app.core.game_engine import game_engine game_engine.set_connection_manager(connection_manager) # Include API routes app.include_router(health.router, prefix="/api", tags=["health"]) app.include_router(auth.router, prefix="/api/auth", tags=["auth"]) app.include_router(games.router, prefix="/api/games", tags=["games"]) app.include_router(teams.router, prefix="/api/teams", tags=["teams"]) @app.get("/") async def root(): return {"message": "Paper Dynasty Game Backend", "version": "1.0.0"} if __name__ == "__main__": import uvicorn uvicorn.run( "app.main:socket_app", host="0.0.0.0", port=8000, reload=True, log_level="info" )