diff --git a/py/src/braintrust/logger.py b/py/src/braintrust/logger.py index 9a65dee3..3b2532d5 100644 --- a/py/src/braintrust/logger.py +++ b/py/src/braintrust/logger.py @@ -382,6 +382,18 @@ def __exit__( NOOP_SPAN: Span = _NoopSpan() NOOP_SPAN_PERMALINK = "https://www.braintrust.dev/noop-span" +_V1_PROXY_SUFFIX = "/v1/proxy" + + +def _normalize_proxy_conn_url(proxy_url: str) -> str: + # proxy_url may point at the universal proxy (`{api_url}/v1/proxy`) for + # EU/self-hosted orgs, but proxy_conn only targets Braintrust API endpoints + # (e.g. function/invoke, function/sandbox-list) served at the API host root. + # Drop the suffix so these requests resolve on all data planes. + if proxy_url.endswith(_V1_PROXY_SUFFIX): + return proxy_url[: -len(_V1_PROXY_SUFFIX)] + return proxy_url + class BraintrustState: def __init__(self): @@ -609,7 +621,7 @@ def proxy_conn(self): if not self._proxy_conn: if not self.proxy_url: raise RuntimeError("Must initialize proxy_url before requesting proxy_conn") - self._proxy_conn = HTTPConnection(self.proxy_url, adapter=_http_adapter) + self._proxy_conn = HTTPConnection(_normalize_proxy_conn_url(self.proxy_url), adapter=_http_adapter) return self._proxy_conn def user_info(self) -> Mapping[str, Any]: diff --git a/py/src/braintrust/test_logger.py b/py/src/braintrust/test_logger.py index 3fc5c833..459f4b06 100644 --- a/py/src/braintrust/test_logger.py +++ b/py/src/braintrust/test_logger.py @@ -3868,6 +3868,20 @@ def test_check_org_info_with_git_metadata_uses_server_settings(): assert set(state.git_metadata_settings.fields) == {"commit", "branch"} +def test_proxy_conn_strips_v1_proxy_suffix(): + """EU/self-hosted proxy_url ends in /v1/proxy; proxy_conn must target the API host root.""" + state = BraintrustState() + state.proxy_url = "https://api-eu.braintrust.dev/v1/proxy" + assert state.proxy_conn().base_url == "https://api-eu.braintrust.dev" + + +def test_proxy_conn_leaves_bare_host_unchanged(): + """A bare proxy host (US default) is used as-is.""" + state = BraintrustState() + state.proxy_url = "https://api.braintrust.dev" + assert state.proxy_conn().base_url == "https://api.braintrust.dev" + + def test_get_repo_info_without_settings_returns_none(): """Direct call to get_repo_info with settings=None should return None.""" assert get_repo_info(None) is None