import socket import threading import time import traceback BACKEND_HOST = "127.0.0.1" BACKEND_BIND_HOST = "0.0.0.0" BACKEND_PORT = 8000 _backend_thread = None _backend_error = None def is_port_open(host: str = BACKEND_HOST, port: int = BACKEND_PORT) -> bool: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.settimeout(0.5) try: s.connect((host, port)) return True except Exception: return False def _run_backend_in_thread() -> None: global _backend_error try: import uvicorn import backend_main app = getattr(backend_main, "app", None) if app is None: raise RuntimeError("backend_main.app wurde nicht gefunden.") config = uvicorn.Config( app=app, host=BACKEND_BIND_HOST, port=BACKEND_PORT, log_level="info", ) server = uvicorn.Server(config) server.run() except Exception: _backend_error = traceback.format_exc() def start_backend(timeout_seconds: float = 20.0) -> bool: global _backend_thread if is_port_open(): return True if _backend_thread is None or not _backend_thread.is_alive(): _backend_thread = threading.Thread( target=_run_backend_in_thread, name="aza-local-backend", daemon=True, ) _backend_thread.start() deadline = time.time() + timeout_seconds while time.time() < deadline: if is_port_open(): return True if _backend_error: return False time.sleep(0.25) return False def get_backend_error() -> str: return _backend_error or "" if __name__ == "__main__": ok = start_backend() print("backend_started:", ok) if not ok and _backend_error: print(_backend_error)