litellm/tests/rust-python-harness/shared/parity/local_server.py
yujonglee ee08c36fc0
refactor(tests): restructure rust python harness around strategy definitions (#39628)
* wip

* refactor(tests): move sdk function tracing into rust python harness

* dead code

* fix: handle harness keyboard interrupts

* refactor(tests): deduplicate rust python harness helpers

* fix(harness): expose validated strategy choices

* wip

* refactor(harness): let strategies own parity reports

* docs(harness): update strategy structure

* refactor(harness): localize strategy report views

* wip

* fix(harness): satisfy mapping runner type checks

* fix(harness): clarify trace parity output

* wip

* fix(harness): clarify unit mapping report

* fix(harness): finalize trace parity contracts

* refactor(harness): structure parity contracts

* feat: derive unit test mapping from traces

* feat(harness): map rstest test families

* feat(ocr): port Azure document intelligence tests

* feat(harness): enforce complete unit mappings

* feat(ocr): add reducto core transforms

* feat(harness): classify host-only unit tests

* fix(ocr): complete Rust provider plumbing

* fix(harness): reuse OCR parity workers
2026-09-03 21:15:01 -07:00

56 lines
1.5 KiB
Python

from __future__ import annotations
import threading
from collections.abc import Generator, Iterable
from contextlib import contextmanager
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from typing import Final, TypeVar
class LocalHttpServer(ThreadingHTTPServer):
daemon_threads = True
@property
def url(self) -> str:
return f"http://127.0.0.1:{self.server_address[1]}"
class LocalHttpHandler(BaseHTTPRequestHandler):
protocol_version = "HTTP/1.1"
def write_chunk(self, chunk: bytes) -> None:
self.wfile.write(f"{len(chunk):X}\r\n".encode("ascii"))
self.wfile.write(chunk)
self.wfile.write(b"\r\n")
self.wfile.flush()
def finish_chunked(self) -> None:
self.wfile.write(b"0\r\n\r\n")
self.wfile.flush()
def write_chunked(self, chunks: Iterable[bytes]) -> None:
for chunk in chunks:
self.write_chunk(chunk)
self.finish_chunked()
def log_message(self, format: str, *args: object) -> None:
return
ServerT = TypeVar("ServerT", bound=LocalHttpServer)
@contextmanager
def serve_in_thread(server: ServerT, poll_interval: float = 0.5) -> Generator[ServerT]:
thread: Final = threading.Thread(
target=server.serve_forever,
kwargs={"poll_interval": poll_interval},
daemon=True,
)
thread.start()
try:
yield server
finally:
server.shutdown()
server.server_close()
thread.join(timeout=5)