250 lines
7.2 KiB
Python
250 lines
7.2 KiB
Python
#!/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()
|