mirror of
https://github.com/debpalash/VoiceStudio.git
synced 2026-10-02 01:26:35 +08:00
Refresh SDK connection pools when network settings change
This commit is contained in:
@@ -34,8 +34,17 @@ def _check_sdk_request(request):
|
||||
raise ValueError("SDK provider requests require HTTPS outside localhost")
|
||||
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
def _sdk_http_client():
|
||||
# Settings can update proxies without restarting the backend. Retire the
|
||||
# previous pool without closing responses still being streamed from it.
|
||||
keys = ("HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY", "NO_PROXY",
|
||||
"http_proxy", "https_proxy", "all_proxy", "no_proxy",
|
||||
"SSL_CERT_FILE", "SSL_CERT_DIR", "REQUEST_METHOD")
|
||||
return _sdk_http_client_for_env(tuple(os.environ.get(key) for key in keys))
|
||||
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
def _sdk_http_client_for_env(network_env):
|
||||
# A shared thread-safe pool also keeps streaming responses alive after
|
||||
# completion() returns. It carries no provider credentials of its own.
|
||||
import httpx
|
||||
|
||||
@@ -153,3 +153,5 @@ Anthropic, Bedrock, and Vertex requests.
|
||||
The shared HTTP client bypasses environment proxies for loopback requests so local
|
||||
prompts stay local, preserves proxy settings for remote HTTPS providers, and never
|
||||
stores response cookies between provider requests.
|
||||
Changing proxy settings refreshes the pool for subsequent requests while existing
|
||||
streams keep their original connections until they finish.
|
||||
|
||||
@@ -165,7 +165,7 @@ def test_anthropic_does_not_follow_credentialed_redirect(registry):
|
||||
def test_sdk_pool_keeps_loopback_direct_and_does_not_persist_cookies(monkeypatch, proxy_enabled):
|
||||
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
||||
from threading import Thread
|
||||
from services.llm_transport import _sdk_http_client
|
||||
from services.llm_transport import _sdk_http_client_for_env
|
||||
seen = []
|
||||
class Handler(BaseHTTPRequestHandler):
|
||||
def log_message(self, *args): pass
|
||||
@@ -182,7 +182,7 @@ def test_sdk_pool_keeps_loopback_direct_and_does_not_persist_cookies(monkeypatch
|
||||
server = ThreadingHTTPServer(("127.0.0.1", 0), Handler)
|
||||
thread = Thread(target=server.serve_forever, daemon=True); thread.start()
|
||||
try:
|
||||
with _sdk_http_client.__wrapped__() as client:
|
||||
with _sdk_http_client_for_env.__wrapped__(()) as client:
|
||||
for _ in range(2):
|
||||
assert client.get(f"http://127.0.0.1:{server.server_port}/", timeout=2).status_code == 200
|
||||
assert not list(client.cookies.jar)
|
||||
@@ -195,7 +195,7 @@ def test_sdk_remote_https_still_uses_environment_proxy(monkeypatch):
|
||||
import httpx
|
||||
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
||||
from threading import Thread
|
||||
from services.llm_transport import _sdk_http_client
|
||||
from services.llm_transport import _sdk_http_client_for_env
|
||||
seen = []
|
||||
class Handler(BaseHTTPRequestHandler):
|
||||
def log_message(self, *args): pass
|
||||
@@ -211,9 +211,23 @@ def test_sdk_remote_https_still_uses_environment_proxy(monkeypatch):
|
||||
monkeypatch.setenv("NO_PROXY", "")
|
||||
monkeypatch.setenv("no_proxy", "")
|
||||
try:
|
||||
with _sdk_http_client.__wrapped__() as client:
|
||||
with _sdk_http_client_for_env.__wrapped__(()) as client:
|
||||
with pytest.raises(httpx.ProxyError, match="502"):
|
||||
client.get("https://provider.invalid/", timeout=2)
|
||||
assert seen == ["provider.invalid:443"]
|
||||
finally:
|
||||
server.shutdown(); server.server_close(); thread.join(timeout=2)
|
||||
|
||||
|
||||
def test_sdk_pool_refreshes_after_proxy_change_without_closing_active_streams(monkeypatch):
|
||||
from services.llm_transport import _sdk_http_client
|
||||
monkeypatch.setenv("HTTPS_PROXY", "http://127.0.0.1:8011")
|
||||
monkeypatch.setenv("https_proxy", "http://127.0.0.1:8011")
|
||||
first = _sdk_http_client()
|
||||
assert _sdk_http_client() is first
|
||||
monkeypatch.setenv("HTTPS_PROXY", "http://127.0.0.1:8012")
|
||||
monkeypatch.setenv("https_proxy", "http://127.0.0.1:8012")
|
||||
second = _sdk_http_client()
|
||||
assert second is not first
|
||||
assert not first.is_closed
|
||||
assert not second.is_closed
|
||||
|
||||
Reference in New Issue
Block a user