#!/usr/bin/env python3 """ HuggingFace Spaces Startup Script Handles bot and server startup with proper port management """ import os import sys import time import signal import socket import subprocess from pathlib import Path PORT = int(os.environ.get("PORT", 7860)) def is_port_in_use(port): """Check if a port is in use""" with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: return s.connect_ex(('localhost', port)) == 0 def kill_port_process(port): """Kill process using a specific port""" try: # Try fuser first result = subprocess.run( f"fuser -k {port}/tcp", shell=True, capture_output=True, timeout=5 ) if result.returncode == 0: print(f"โœ… Killed process on port {port} using fuser") return True except: pass try: # Try lsof result = subprocess.run( f"lsof -t -i:{port}", shell=True, capture_output=True, timeout=5 ) if result.returncode == 0: pids = result.stdout.decode().strip().split('\n') for pid in pids: if pid: os.kill(int(pid), signal.SIGKILL) print(f"โœ… Killed process(es) on port {port} using lsof") return True except: pass return False def start_bot(): """Start the Ultroid bot in background""" print("๐Ÿค– Starting Ultroid bot...") print(f" SESSION1 env: {'SET' if os.environ.get('SESSION1') else 'NOT SET'}") print(f" Current dir: {os.getcwd()}") # Don't pipe output - let it show in logs if os.environ.get("SESSION1"): bot_process = subprocess.Popen( [sys.executable, "multi_client.py"] ) else: bot_process = subprocess.Popen( [sys.executable, "-m", "pyUltroid"] ) print(f"โœ… Bot process started with PID: {bot_process.pid}") # Check if process is still running after 1 second time.sleep(1) if bot_process.poll() is not None: print(f"โŒ Bot process died immediately! Exit code: {bot_process.returncode}") else: print(f"โœ… Bot is running") return bot_process def start_server(port): """Start the FastAPI server""" print(f"๐Ÿš€ Starting API server on port {port}...") # Import and run server os.environ["PORT"] = str(port) # Run server.py directly subprocess.run([sys.executable, "server.py"]) def main(): print("=" * 50) print("๐Ÿš€ Ultroid HuggingFace Startup (Python)") print("=" * 50) # Change to repo directory repo_dir = Path("/app/repo") if repo_dir.exists(): os.chdir(repo_dir) print(f"๐Ÿ“‚ Working directory: {repo_dir}") else: print(f"โŒ Repo directory not found: {repo_dir}") sys.exit(1) # Debug: Show environment print(f"๐Ÿ” Environment check:") print(f" PORT: {PORT}") print(f" SESSION1: {'SET โœ…' if os.environ.get('SESSION1') else 'NOT SET โš ๏ธ'}") print(f" API_ID: {'SET โœ…' if os.environ.get('API_ID') else 'NOT SET โŒ'}") print(f" API_HASH: {'SET โœ…' if os.environ.get('API_HASH') else 'NOT SET โŒ'}") print(f" SESSION: {'SET โœ…' if os.environ.get('SESSION') else 'NOT SET โŒ'}") # Check if port is in use if is_port_in_use(PORT): print(f"โš ๏ธ Port {PORT} is already in use!") print(f"๐Ÿงน Attempting to free port {PORT}...") if kill_port_process(PORT): time.sleep(2) if is_port_in_use(PORT): print(f"โŒ Failed to free port {PORT}") sys.exit(1) else: print(f"โš ๏ธ Could not kill process on port {PORT}") else: print(f"โœ… Port {PORT} is available") # Start bot in background bot_process = start_bot() # Wait for bot to initialize print("โณ Waiting 5 seconds for bot to initialize...") time.sleep(5) # Check if bot is still running if bot_process.poll() is not None: print(f"โŒ WARNING: Bot process died! Exit code: {bot_process.returncode}") print(f"โš ๏ธ Server will start anyway, but bot is NOT running!") else: print(f"โœ… Bot is still running (PID: {bot_process.pid})") # Check port one more time before starting server if is_port_in_use(PORT): print(f"โŒ Port {PORT} was taken while bot was starting!") kill_port_process(PORT) time.sleep(2) # Start server (blocks here) print(f"๐Ÿ“Š Dashboard will be available on port {PORT}") print("=" * 50) start_server(PORT) if __name__ == "__main__": main()