Catalyst / admin/AirportCyberSimulator 14.8 GB / 57.8 GB 40.0 GB free
Help Sign in

admin / AirportCyberSimulator

public

Airport Cyber Attack Simulation Application

Code Issues Pull requests Pipelines Packages Security Insights Wiki Settings
AirportCyberSimulator / airport-cyber-sim-v2-exe / src / run.py 1521 B · main
 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
"""
Standalone launcher for the Airport Cyber Resilience Simulator (Windows .exe).

Starts the bundled FastAPI/uvicorn server on localhost and opens the kiosk in the
default browser. Everything (Python runtime, dependencies, static assets, fonts,
data) is packed into the executable, so it runs fully offline.
"""
from __future__ import annotations

import multiprocessing
import socket
import sys
import threading
import webbrowser

import uvicorn

from main import app

HOST = "127.0.0.1"
PREFERRED_PORT = 8000


def find_free_port(preferred: int) -> int:
    """Use the preferred port if available, otherwise let the OS pick one."""
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        try:
            s.bind((HOST, preferred))
            return preferred
        except OSError:
            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s2:
                s2.bind((HOST, 0))
                return s2.getsockname()[1]


def main() -> None:
    multiprocessing.freeze_support()  # safe no-op guard for frozen Windows builds
    port = find_free_port(PREFERRED_PORT)
    url = f"http://{HOST}:{port}"

    print("=" * 60)
    print(" Airport Cyber Resilience Simulator — V2 (offline build)")
    print(f" Serving at {url}")
    print(" A browser window will open. Close this console to stop.")
    print("=" * 60)

    threading.Timer(1.5, lambda: webbrowser.open(url)).start()
    uvicorn.run(app, host=HOST, port=port, log_level="warning")


if __name__ == "__main__":
    main()