#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Hugging Face Space launcher for MatrixGame WebSocket Server This script launches the server with the appropriate configuration for Hugging Face Spaces. """ import os import sys import subprocess import logging import asyncio from server import init_app from aiohttp import web # Configure logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) async def run_async(): """Run the server using the async API directly for better stability""" # Get the port from environment variable in Hugging Face Space port = int(os.environ.get("PORT", 7860)) # Determine if this is running in a Hugging Face Space is_hf_space = os.environ.get("SPACE_ID") is not None # Set the base path if in a space base_path = "" if is_hf_space: # In Hugging Face Spaces, we're usually behind a proxy space_id = os.environ.get('SPACE_ID', '') # Use empty base path for better WebSocket compatibility # WebSockets often have trouble with subpaths in proxied environments base_path = "" # or f"/{space_id}" if needed logger.info(f"Running in Hugging Face Space {space_id}") logger.info(f"Initializing application with base_path='{base_path}', port={port}") # Initialize the application app = await init_app(base_path=base_path) # Log all routes for debugging routes = sorted([f"{route.method} {route.resource}" for route in app.router.routes() if hasattr(route, 'resource')]) logger.info(f"Registered {len(routes)} routes:") for route in routes: logger.info(f" - {route}") # Start the server logger.info(f"Starting server on 0.0.0.0:{port}") runner = web.AppRunner(app) await runner.setup() site = web.TCPSite(runner, '0.0.0.0', port) await site.start() # Keep the server running logger.info("Server started, running indefinitely...") while True: await asyncio.sleep(3600) # Sleep for an hour def main(): """Run using the subprocess method (fallback)""" # Get the port from environment variable in Hugging Face Space port = int(os.environ.get("PORT", 7860)) # Determine if this is running in a Hugging Face Space is_hf_space = os.environ.get("SPACE_ID") is not None # Pass the appropriate path if in a space path_arg = "" if is_hf_space: # In a space, we're usually behind a proxy, so we need to handle base path # We use empty base path for better WebSocket compatibility path_arg = "" # or f"--path /{os.environ.get('SPACE_ID', '')}" if needed # Construct and run the command cmd = f"{sys.executable} server.py --host 0.0.0.0 --port {port} {path_arg}" print(f"Running command: {cmd}") subprocess.run(cmd, shell=True) if __name__ == "__main__": # First try to run using the async API try: logger.info("Starting server using async API") asyncio.run(run_async()) except Exception as e: logger.error(f"Failed to run using async API: {e}", exc_info=True) logger.info("Falling back to subprocess method") main()