""" Enhanced Production Server Integrates all services for comprehensive crypto data tracking with real-time updates, persistence, and scheduling """ import asyncio import logging from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles from contextlib import asynccontextmanager import uvicorn import os # Import services from backend.services.unified_config_loader import UnifiedConfigLoader from backend.services.scheduler_service import SchedulerService from backend.services.persistence_service import PersistenceService from backend.services.websocket_service import WebSocketService # Import database manager try: from database.db_manager import DatabaseManager except ImportError: DatabaseManager = None # Import routers from backend.routers.integrated_api import router as integrated_router, set_services from backend.routers.advanced_api import router as advanced_router # Setup logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) # Global service instances config_loader = None scheduler_service = None persistence_service = None websocket_service = None db_manager = None @asynccontextmanager async def lifespan(app: FastAPI): """Lifespan context manager for startup and shutdown""" global config_loader, scheduler_service, persistence_service, websocket_service, db_manager logger.info("=" * 80) logger.info("π Starting Enhanced Crypto Data Tracker") logger.info("=" * 80) try: # Initialize database manager if DatabaseManager: db_manager = DatabaseManager("data/crypto_tracker.db") db_manager.init_database() logger.info("β Database initialized") else: logger.warning("β Database manager not available") # Initialize configuration loader logger.info("π₯ Loading configurations...") config_loader = UnifiedConfigLoader() logger.info(f"β Loaded {len(config_loader.apis)} APIs from config files") # Initialize persistence service logger.info("πΎ Initializing persistence service...") persistence_service = PersistenceService(db_manager=db_manager) logger.info("β Persistence service ready") # Initialize scheduler service logger.info("β° Initializing scheduler service...") scheduler_service = SchedulerService( config_loader=config_loader, db_manager=db_manager ) # Initialize WebSocket service logger.info("π Initializing WebSocket service...") websocket_service = WebSocketService( scheduler_service=scheduler_service, persistence_service=persistence_service ) logger.info("β WebSocket service ready") # Set services in router set_services(config_loader, scheduler_service, persistence_service, websocket_service) logger.info("β Services registered with API router") # Setup data update callback def data_update_callback(api_id: str, data: dict): """Callback for data updates from scheduler""" # Save to persistence asyncio.create_task(persistence_service.save_api_data( api_id, data, metadata={'source': 'scheduler'} )) # Notify WebSocket clients asyncio.create_task(websocket_service.notify_data_update( api_id, data, metadata={'source': 'scheduler'} )) # Register callback with scheduler (for each API) for api_id in config_loader.apis.keys(): scheduler_service.register_callback(api_id, data_update_callback) logger.info("β Data update callbacks registered") # Start scheduler logger.info("βΆοΈ Starting scheduler...") await scheduler_service.start() logger.info("β Scheduler started") logger.info("=" * 80) logger.info("β All services started successfully!") logger.info("=" * 80) logger.info("") logger.info("π Service Summary:") logger.info(f" β’ APIs configured: {len(config_loader.apis)}") logger.info(f" β’ Categories: {len(config_loader.get_categories())}") logger.info(f" β’ Scheduled tasks: {len(scheduler_service.tasks)}") logger.info(f" β’ Real-time tasks: {len(scheduler_service.realtime_tasks)}") logger.info("") logger.info("π Access points:") logger.info(" β’ Main Dashboard: http://localhost:8000/") logger.info(" β’ API Documentation: http://localhost:8000/docs") logger.info(" β’ WebSocket: ws://localhost:8000/api/v2/ws") logger.info("") yield # Shutdown logger.info("") logger.info("=" * 80) logger.info("π Shutting down services...") logger.info("=" * 80) # Stop scheduler if scheduler_service: logger.info("βΈοΈ Stopping scheduler...") await scheduler_service.stop() logger.info("β Scheduler stopped") # Create final backup if persistence_service: logger.info("πΎ Creating final backup...") try: backup_file = await persistence_service.backup_all_data() logger.info(f"β Backup created: {backup_file}") except Exception as e: logger.error(f"β Backup failed: {e}") logger.info("=" * 80) logger.info("β Shutdown complete") logger.info("=" * 80) except Exception as e: logger.error(f"β Error during startup: {e}", exc_info=True) raise # Create FastAPI app app = FastAPI( title="Enhanced Crypto Data Tracker", description="Comprehensive cryptocurrency data tracking with real-time updates, persistence, and scheduling", version="2.0.0", lifespan=lifespan ) # CORS middleware app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Include routers app.include_router(integrated_router) app.include_router(advanced_router) # Mount static files try: app.mount("/static", StaticFiles(directory="static"), name="static") except: logger.warning("β Static files directory not found") # Serve HTML files from fastapi.responses import HTMLResponse, FileResponse @app.get("/", response_class=HTMLResponse) async def root(): """Serve main dashboard""" if os.path.exists("index.html"): return FileResponse("index.html") else: return HTMLResponse("""
Real-time cryptocurrency data tracking and monitoring