Studio: ignore unsupported env proxy during Studio startup (#6102)

* fix: ignore unsupported env proxy during Studio startup

* fix: handle missing socksio env proxy at startup

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Match printf logging style and inline the proxy predicate for PR #6102

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Daniel Han <danielhanchen@gmail.com>
This commit is contained in:
Lee Jackson 2026-06-11 13:13:27 +01:00 committed by GitHub
commit 49024462f3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 98 additions and 3 deletions

View file

@ -469,9 +469,24 @@ def _apply_mistral_reasoning_controls(
# Shared client reused across all requests for HTTP connection pooling.
# Auth headers and timeouts are per-request, so one client handles every
# provider without storing credentials.
_http_client = httpx.AsyncClient()
# Auth headers and timeouts are passed per-request, so a single client
# handles every provider without storing credentials.
def _create_shared_http_client() -> httpx.AsyncClient:
# Unsupported env proxy schemes (socks:// etc) raise at construction and
# would crash Studio startup (#6090); retry ignoring env proxies instead.
try:
return httpx.AsyncClient()
except (ImportError, ValueError) as exc:
exc_str = str(exc)
if "Unknown scheme for proxy URL" not in exc_str and "socksio" not in exc_str:
raise
logger.warning(
"Ignoring unsupported environment proxy for the shared HTTP client: %s", exc_str
)
return httpx.AsyncClient(trust_env = False)
_http_client = _create_shared_http_client()
# Cap per-image fetch well below Gemini's ~20 MB total request budget.

View file

@ -0,0 +1,80 @@
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
from pathlib import Path
import importlib.util
import sys
_BACKEND_DIR = str(Path(__file__).resolve().parent.parent)
if _BACKEND_DIR not in sys.path:
sys.path.insert(0, _BACKEND_DIR)
_EXTERNAL_PROVIDER_PATH = (
Path(__file__).resolve().parent.parent / "core/inference/external_provider.py"
)
def _load_external_provider_module():
spec = importlib.util.spec_from_file_location(
"external_provider_under_test",
_EXTERNAL_PROVIDER_PATH,
)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def test_shared_http_client_ignores_unsupported_proxy_scheme(monkeypatch):
ep_mod = _load_external_provider_module()
calls = []
class FakeAsyncClient:
def __init__(self, **kwargs):
calls.append(kwargs)
if kwargs.get("trust_env") is not False:
raise ValueError("Unknown scheme for proxy URL URL('socks4://127.0.0.1:12345')")
monkeypatch.setattr(ep_mod.httpx, "AsyncClient", FakeAsyncClient)
client = ep_mod._create_shared_http_client()
assert isinstance(client, FakeAsyncClient)
assert calls == [{}, {"trust_env": False}]
def test_shared_http_client_ignores_missing_socksio(monkeypatch):
ep_mod = _load_external_provider_module()
calls = []
class FakeAsyncClient:
def __init__(self, **kwargs):
calls.append(kwargs)
if kwargs.get("trust_env") is not False:
raise ImportError(
"Using SOCKS proxy, but the 'socksio' package is not installed. "
"Make sure to install httpx using `pip install httpx[socks]`."
)
monkeypatch.setattr(ep_mod.httpx, "AsyncClient", FakeAsyncClient)
client = ep_mod._create_shared_http_client()
assert isinstance(client, FakeAsyncClient)
assert calls == [{}, {"trust_env": False}]
def test_shared_http_client_reraises_other_value_errors(monkeypatch):
ep_mod = _load_external_provider_module()
class FakeAsyncClient:
def __init__(self, **kwargs):
raise ValueError("different httpx setup error")
monkeypatch.setattr(ep_mod.httpx, "AsyncClient", FakeAsyncClient)
try:
ep_mod._create_shared_http_client()
except ValueError as exc:
assert str(exc) == "different httpx setup error"
else:
raise AssertionError("expected ValueError")