7e63e6ea45
- resource_path.py: frozen/dev path resolution for bundled data files - app_desktop.py: pywebview entry point (Dash in daemon thread) - app.spec: PyInstaller onedir config with data files and hidden imports - Updated queries.py, card_browser.py, app.py to use get_resource_path() - Added pywebview + pyinstaller to project dependencies - Fixed unresolved merge conflict in .gitignore - Removed stale 01_nhs_classic.html and AdditionalAnalytics.md
63 lines
1.7 KiB
Python
63 lines
1.7 KiB
Python
"""Desktop entry point: Dash app inside a pywebview native window."""
|
|
|
|
import sys
|
|
import socket
|
|
import threading
|
|
import time
|
|
from pathlib import Path
|
|
|
|
# Ensure src/ is on sys.path so that core/, data_processing/, etc. are importable
|
|
_src_dir = str(Path(__file__).resolve().parent / "src")
|
|
if _src_dir not in sys.path:
|
|
sys.path.insert(0, _src_dir)
|
|
|
|
import webview
|
|
from dash_app.app import app
|
|
|
|
|
|
def find_free_port(start: int = 8050) -> int:
|
|
"""Find the first available port starting from *start*."""
|
|
for port in range(start, start + 100):
|
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
|
try:
|
|
s.bind(("127.0.0.1", port))
|
|
return port
|
|
except OSError:
|
|
continue
|
|
raise RuntimeError("No free port found")
|
|
|
|
|
|
def wait_for_server(port: int, timeout: float = 30.0) -> None:
|
|
"""Block until the Dash server accepts connections."""
|
|
deadline = time.monotonic() + timeout
|
|
while time.monotonic() < deadline:
|
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
|
if s.connect_ex(("127.0.0.1", port)) == 0:
|
|
return
|
|
time.sleep(0.1)
|
|
raise TimeoutError(f"Server did not start within {timeout}s")
|
|
|
|
|
|
def main() -> None:
|
|
port = find_free_port()
|
|
|
|
server_thread = threading.Thread(
|
|
target=app.run,
|
|
kwargs={"debug": False, "port": port, "use_reloader": False},
|
|
daemon=True,
|
|
)
|
|
server_thread.start()
|
|
wait_for_server(port)
|
|
|
|
webview.create_window(
|
|
"NHS Pathway Analysis",
|
|
f"http://127.0.0.1:{port}",
|
|
width=1400,
|
|
height=900,
|
|
)
|
|
webview.start()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|