import json import queue import threading _clients = set() _clients_lock = threading.Lock() def stream_events(): q = queue.Queue() with _clients_lock: _clients.add(q) try: yield 'data: {"type":"connected"}\n\n' while True: try: payload = q.get(timeout=20) yield f"data: {payload}\n\n" except queue.Empty: yield ": heartbeat\n\n" finally: with _clients_lock: _clients.discard(q) def broadcast(data): payload = json.dumps(data) with _clients_lock: clients = list(_clients) for q in clients: q.put_nowait(payload)