96 lines
3.0 KiB
Python
Executable File
96 lines
3.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Safe startup script that handles port conflicts automatically
|
|
"""
|
|
import os
|
|
import sys
|
|
import time
|
|
import socket
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
# Get project root and virtual environment
|
|
PROJECT_ROOT = Path(__file__).parent.absolute()
|
|
VENV_PYTHON = PROJECT_ROOT / ".venv" / "bin" / "python"
|
|
|
|
# Use the virtual environment Python if it exists
|
|
if VENV_PYTHON.exists():
|
|
python_executable = str(VENV_PYTHON)
|
|
print(f"✅ Using virtual environment: {python_executable}")
|
|
else:
|
|
python_executable = sys.executable
|
|
print(f"⚠️ Virtual environment not found, using system Python: {python_executable}")
|
|
|
|
def check_port_available(port, host='127.0.0.1'):
|
|
"""Check if a port is available"""
|
|
try:
|
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
|
|
sock.settimeout(1)
|
|
result = sock.connect_ex((host, port))
|
|
return result != 0
|
|
except Exception:
|
|
return True
|
|
|
|
def find_free_port(start_port, host='127.0.0.1'):
|
|
"""Find a free port starting from start_port"""
|
|
for port in range(start_port, start_port + 20):
|
|
if check_port_available(port, host):
|
|
return port
|
|
raise RuntimeError(f"Could not find a free port starting from {start_port}")
|
|
|
|
# PROJECT_ROOT already defined above
|
|
|
|
# Find available ports
|
|
backend_port = 8000
|
|
frontend_port = 8001
|
|
|
|
if not check_port_available(backend_port):
|
|
new_backend_port = find_free_port(8002)
|
|
print(f"⚠️ Port {backend_port} in use, using {new_backend_port} for backend")
|
|
backend_port = new_backend_port
|
|
|
|
if not check_port_available(frontend_port):
|
|
new_frontend_port = find_free_port(8003)
|
|
print(f"⚠️ Port {frontend_port} in use, using {new_frontend_port} for frontend")
|
|
frontend_port = new_frontend_port
|
|
|
|
print(f"\n🚀 Starting servers:")
|
|
print(f" Backend: http://127.0.0.1:{backend_port}")
|
|
print(f" Frontend: http://127.0.0.1:{frontend_port}")
|
|
print(f" API Docs: http://127.0.0.1:{backend_port}/docs\n")
|
|
|
|
# Start backend
|
|
os.chdir(PROJECT_ROOT / "backend")
|
|
backend_cmd = [
|
|
python_executable, "-m", "uvicorn",
|
|
"app.main:app", "--reload",
|
|
f"--host=0.0.0.0", f"--port={backend_port}"
|
|
]
|
|
|
|
backend_process = subprocess.Popen(backend_cmd)
|
|
print("✅ Backend server starting...")
|
|
time.sleep(3)
|
|
|
|
# Start frontend
|
|
os.chdir(PROJECT_ROOT / "frontend")
|
|
frontend_env = os.environ.copy()
|
|
frontend_env["VITE_DEV_SERVER_PORT"] = str(frontend_port)
|
|
frontend_env["VITE_API_BASE_URL"] = f"http://localhost:{backend_port}"
|
|
frontend_env["VITE_API_BASE_URL_WITH_PREFIX"] = f"http://localhost:{backend_port}/api"
|
|
|
|
frontend_process = subprocess.Popen([python_executable, "start_dev_server.py"], env=frontend_env)
|
|
print("✅ Frontend server starting...")
|
|
|
|
print(f"\n🌟 Both servers are running!")
|
|
print(f" Open: http://127.0.0.1:{frontend_port}")
|
|
print(f" Press Ctrl+C to stop both servers\n")
|
|
|
|
try:
|
|
while True:
|
|
time.sleep(1)
|
|
except KeyboardInterrupt:
|
|
print("\n🛑 Stopping servers...")
|
|
backend_process.terminate()
|
|
frontend_process.terminate()
|
|
print("✅ Servers stopped!")
|