File size: 3,443 Bytes
b8eae92
 
 
 
 
 
 
 
 
 
 
a337ed2
 
0de48cd
a337ed2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0de48cd
 
 
 
 
 
a337ed2
0de48cd
a337ed2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b8eae92
 
a337ed2
b8eae92
 
 
 
 
 
 
 
 
 
a337ed2
 
b8eae92
 
 
 
 
 
 
a337ed2
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#!/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, parse_args
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}")
    
    # Parse default args and override for HF Space
    args = parse_args()
    args.port = port
    args.host = "0.0.0.0" 
    args.path = base_path
    
    # Initialize the application
    app = await init_app(args, 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()