| 29 | |
| 30 | @contextmanager |
| 31 | def local_sse_server() -> Iterator[str]: |
| 32 | if not shutil.which("uv"): |
| 33 | raise RuntimeError( |
| 34 | "uv is not installed. Please install it: " |
| 35 | "https://docs.astral.sh/uv/getting-started/installation/" |
| 36 | ) |
| 37 | |
| 38 | sse_port = _choose_port() |
| 39 | sse_url = f"http://{SSE_HOST}:{sse_port}/sse" |
| 40 | server_file = Path(__file__).resolve().parents[1] / "sse_example" / "server.py" |
| 41 | |
| 42 | print(f"Starting local SSE server at {sse_url} ...", flush=True) |
| 43 | env = os.environ.copy() |
| 44 | env.setdefault("SSE_HOST", SSE_HOST) |
| 45 | env["SSE_PORT"] = str(sse_port) |
| 46 | process: subprocess.Popen[Any] | None = None |
| 47 | |
| 48 | try: |
| 49 | process = subprocess.Popen(["uv", "run", str(server_file)], env=env) |
| 50 | time.sleep(3) |
| 51 | yield sse_url |
| 52 | finally: |
| 53 | if process is not None: |
| 54 | process.terminate() |
| 55 | try: |
| 56 | process.wait(timeout=5) |
| 57 | except subprocess.TimeoutExpired: |
| 58 | process.kill() |
| 59 | process.wait() |
| 60 | |
| 61 | |
| 62 | async def run(url: str, name: str) -> None: |