mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-06 08:16:43 +00:00
* 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
56 lines
1.5 KiB
Python
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)
|