#!/usr/bin/env python3 """ GSPro Remote - Development Server Startup Script Simple Python script to start both backend and frontend servers """ import os import platform import subprocess import sys import time import webbrowser from pathlib import Path # Colors for terminal output class Colors: HEADER = "\033[95m" OKBLUE = "\033[94m" OKCYAN = "\033[96m" OKGREEN = "\033[92m" WARNING = "\033[93m" FAIL = "\033[91m" ENDC = "\033[0m" BOLD = "\033[1m" def print_header(text): print(f"\n{Colors.HEADER}{Colors.BOLD}{'=' * 50}{Colors.ENDC}") print(f"{Colors.HEADER}{Colors.BOLD}{text}{Colors.ENDC}") print(f"{Colors.HEADER}{Colors.BOLD}{'=' * 50}{Colors.ENDC}\n") def print_success(text): print(f"{Colors.OKGREEN}✓ {text}{Colors.ENDC}") def print_error(text): print(f"{Colors.FAIL}✗ {text}{Colors.ENDC}") def print_info(text): print(f"{Colors.OKCYAN}→ {text}{Colors.ENDC}") def check_python(): """Check if Python is installed and version is 3.11+""" version = sys.version_info if version.major < 3 or (version.major == 3 and version.minor < 11): print_error(f"Python 3.11+ required, found {version.major}.{version.minor}") return False print_success(f"Python {version.major}.{version.minor} found") return True def check_node(): """Check if Node.js is installed""" try: result = subprocess.run(["node", "--version"], capture_output=True, text=True) if result.returncode == 0: print_success(f"Node.js {result.stdout.strip()} found") return True except FileNotFoundError: pass print_error("Node.js not found. Please install from https://nodejs.org/") return False def check_npm(): """Check if npm is installed""" try: result = subprocess.run(["npm", "--version"], capture_output=True, text=True) if result.returncode == 0: print_success(f"npm {result.stdout.strip()} found") return True except FileNotFoundError: pass print_error("npm not found") return False def setup_backend(backend_dir): """Setup backend virtual environment and dependencies""" venv_path = backend_dir / ".venv" # Create virtual environment if it doesn't exist if not venv_path.exists(): print_info("Creating Python virtual environment...") subprocess.run([sys.executable, "-m", "venv", str(venv_path)], cwd=backend_dir) # Determine the activation script based on OS if platform.system() == "Windows": activate_script = venv_path / "Scripts" / "activate.bat" python_exe = venv_path / "Scripts" / "python.exe" pip_exe = venv_path / "Scripts" / "pip.exe" else: activate_script = venv_path / "bin" / "activate" python_exe = venv_path / "bin" / "python" pip_exe = venv_path / "bin" / "pip" # Check if dependencies are installed result = subprocess.run( [str(pip_exe), "show", "fastapi"], capture_output=True, cwd=backend_dir ) if result.returncode != 0: print_info("Installing backend dependencies...") subprocess.run([str(pip_exe), "install", "-e", "."], cwd=backend_dir) else: print_success("Backend dependencies already installed") return python_exe def setup_frontend(frontend_dir): """Setup frontend dependencies""" node_modules = frontend_dir / "node_modules" if not node_modules.exists(): print_info("Installing frontend dependencies...") subprocess.run(["npm", "install"], cwd=frontend_dir, shell=True) else: print_success("Frontend dependencies already installed") def get_local_ip(): """Get local IP address""" import socket try: # Connect to a public DNS server to get local IP s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("8.8.8.8", 80)) ip = s.getsockname()[0] s.close() return ip except: return "localhost" def main(): print_header("GSPro Remote - Development Server Startup") # Get project directories script_dir = Path(__file__).parent.resolve() backend_dir = script_dir / "backend" frontend_dir = script_dir / "frontend" print(f"Project root: {script_dir}") # Check prerequisites print_header("Checking Prerequisites") if not check_python(): sys.exit(1) if not check_node(): sys.exit(1) if not check_npm(): sys.exit(1) # Setup backend print_header("Setting up Backend") os.chdir(backend_dir) python_exe = setup_backend(backend_dir) # Setup frontend print_header("Setting up Frontend") os.chdir(frontend_dir) setup_frontend(frontend_dir) # Start backend server print_header("Starting Backend Server") backend_cmd = [ str(python_exe), "-m", "uvicorn", "app.main:app", "--reload", "--host", "0.0.0.0", "--port", "5005", "--log-level", "info", ] if platform.system() == "Windows": backend_process = subprocess.Popen( backend_cmd, cwd=backend_dir, creationflags=subprocess.CREATE_NEW_CONSOLE ) else: backend_process = subprocess.Popen(backend_cmd, cwd=backend_dir) print_success("Backend server starting on http://localhost:5005") # Wait for backend to start time.sleep(3) # Start frontend server print_header("Starting Frontend Server") frontend_cmd = "npm run dev -- --host" if platform.system() == "Windows": frontend_process = subprocess.Popen( frontend_cmd, shell=True, cwd=frontend_dir, creationflags=subprocess.CREATE_NEW_CONSOLE, ) else: frontend_process = subprocess.Popen(frontend_cmd, shell=True, cwd=frontend_dir) print_success("Frontend server starting on http://localhost:5173") # Get local IP local_ip = get_local_ip() # Print access information print_header("Servers Started Successfully!") print(f"{Colors.OKGREEN}Access the application at:{Colors.ENDC}") print(f" {Colors.BOLD}Local:{Colors.ENDC} http://localhost:5173") print(f" {Colors.BOLD}Network:{Colors.ENDC} http://{local_ip}:5173") print(f" {Colors.BOLD}Backend API:{Colors.ENDC} http://localhost:5005") print(f" {Colors.BOLD}API Docs:{Colors.ENDC} http://localhost:5005/api/docs") print(f" {Colors.BOLD}mDNS:{Colors.ENDC} http://gsproapp.local:5005") print(f"\n{Colors.WARNING}To access from your phone/tablet:{Colors.ENDC}") print(f"1. Ensure your device is on the same WiFi network") print(f"2. Open a browser and go to: http://{local_ip}:5173") print(f"\n{Colors.BOLD}Press Ctrl+C to stop all servers{Colors.ENDC}\n") # Keep script running and handle shutdown try: # Open browser after a short delay time.sleep(2) webbrowser.open("http://localhost:5173") # Wait for processes backend_process.wait() frontend_process.wait() except KeyboardInterrupt: print(f"\n{Colors.WARNING}Shutting down servers...{Colors.ENDC}") backend_process.terminate() frontend_process.terminate() print_success("Servers stopped") sys.exit(0) if __name__ == "__main__": main()