File size: 3,780 Bytes
c485991
 
 
 
 
01a4a8e
c485991
 
01a4a8e
c485991
01a4a8e
c485991
01a4a8e
c485991
 
 
01a4a8e
c485991
01a4a8e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c485991
 
 
01a4a8e
459ad1b
 
01a4a8e
c485991
459ad1b
01a4a8e
 
 
 
 
 
459ad1b
 
f998aeb
 
74460ff
 
c5c3d01
 
 
 
 
 
 
 
 
 
 
e8ec8ba
74460ff
 
 
c5c3d01
74460ff
 
 
 
 
01a4a8e
459ad1b
 
 
 
 
c5c3d01
459ad1b
 
 
 
 
f998aeb
01a4a8e
 
f998aeb
01a4a8e
f998aeb
c485991
f998aeb
01a4a8e
 
 
 
 
 
 
 
 
 
 
f998aeb
c485991
459ad1b
 
 
 
 
 
c485991
01a4a8e
c485991
 
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import subprocess
import os
import sys
import time


def kill_port_8000():
    try:
        if os.name == "nt":  # Windows
            # Find PID on port 8000
            result = subprocess.run(["netstat", "-ano"], capture_output=True, text=True)
            for line in result.stdout.splitlines():
                if ":8000" in line and "LISTENING" in line:
                    parts = line.split()
                    pid = parts[-1]
                    print(f"Killing process {pid} on port 8000...")
                    subprocess.run(["taskkill", "/F", "/PID", pid], check=False)
                    time.sleep(1)
        else:  # Linux/Mac
            # Use lsof on macOS, fuser on Linux
            import platform

            system = platform.system()
            if system == "Darwin":  # macOS
                result = subprocess.run(
                    ["lsof", "-ti", "tcp:8000"], capture_output=True, text=True
                )
                pids = result.stdout.strip().split("\n")
                for pid in pids:
                    if pid:
                        print(f"Killing process {pid} on port 8000...")
                        subprocess.run(["kill", "-9", pid], check=False)
            else:  # Linux
                subprocess.run(["fuser", "-k", "8000/tcp"], check=False)
    except Exception as e:
        print(f"Error killing port: {e}")


import argparse


def run_server():
    parser = argparse.ArgumentParser(description="Run the ATC Simulation Server")
    parser.add_argument(
        "--ui", "-u", action="store_true", help="Start the backend and the frontend UI"
    )
    parser.add_argument(
        "--only-ui", action="store_true", help="Start ONLY the frontend UI (visualizer)"
    )
    args = parser.parse_args()

    script_dir = os.path.dirname(os.path.abspath(__file__))
    parent_dir = os.path.dirname(script_dir)
    ui_dir = os.path.join(script_dir, "visualizer")

    # Detect pnpm or npm
    def get_pkg_manager():
        # Check if pnpm is available
        try:
            subprocess.run(["pnpm", "--version"], capture_output=True, shell=True, check=True)
            return "pnpm"
        except (subprocess.CalledProcessError, FileNotFoundError):
            return "npm"

    pkg_manager = get_pkg_manager()
    print(f"Using {pkg_manager} for frontend...")

    if args.only_ui:
        print("Starting ONLY Frontend (Vite)...")
        try:
            subprocess.run([pkg_manager, "run", "dev"], cwd=ui_dir, shell=True)
        except KeyboardInterrupt:
            print("\nStopping UI...")
        return

    kill_port_8000()

    # Start UI if flag provided
    ui_process = None
    if args.ui:
        print("Starting Frontend (Vite)...")
        try:
            ui_process = subprocess.Popen([pkg_manager, "run", "dev"], cwd=ui_dir, shell=True)
            print(f"Frontend process started (PID: {ui_process.pid})")
        except Exception as e:
            print(f"Error starting frontend: {e}")

    print("Starting backend...")
    env = os.environ.copy()
    if "PYTHONPATH" in env:
        env["PYTHONPATH"] = parent_dir + os.pathsep + env["PYTHONPATH"]
    else:
        env["PYTHONPATH"] = parent_dir

    try:
        subprocess.run(
            [
                sys.executable,
                "-m",
                "uvicorn",
                "atc_rl_api.api.main:app",
                "--host",
                "0.0.0.0",
                "--port",
                "8000",
            ],
            env=env,
        )
    except KeyboardInterrupt:
        print("\nStopping server...")
    finally:
        if ui_process:
            print("Terminating frontend process...")
            ui_process.terminate()
            ui_process.wait()


if __name__ == "__main__":
    run_server()