Skip to content

Commit 6ba96f2

Browse files
dd-octo-sts[bot]Kyle-VerhoogYun-Kimbrettlangdon
authored
fix(llmobs): support HTTPS_PROXY setting [backport 3.18] (#15165)
Backport 7bc20af from #15130 to 3.18. The built in `http.client` that we use does not support the HTTP{S}_PROXY environment variable (or proxying in general). AI tells me that the fix is pretty straightforward by extending the client. ## Testing I manually validated this solution by installing [squid](https://www.squid-cache.org/) locally with a small test app: ``` # demonstrate the proxy working locally with curl (.venv) ~/d/dd-trace-py ❯❯❯ HTTPS_PROXY=http://127.0.0.1:3128 curl https://google.com (.venv) ~/d/dd-trace-py ❯❯❯ tail -n 1 /opt/homebrew/var/logs/squid/access.log 1762370301.555 185 127.0.0.1 TCP_TUNNEL/200 7488 CONNECT google.com:443 - HIER_DIRECT/142.250.81.238 - (.venv) ~/d/dd-trace-py ❯❯❯ HTTPS_PROXY=http://127.0.0.1:3128 ddtrace-run python openai-app.py (.venv) ~/d/dd-trace-py ❯❯❯ tail -n 2 /opt/homebrew/var/logs/squid/access.log 1762370369.733 169 127.0.0.1 TCP_TUNNEL/200 4049 CONNECT llmobs-intake.datadoghq.com:443 - HIER_DIRECT/3.233.158.217 - 1762370369.845 3857 127.0.0.1 TCP_TUNNEL/200 6469 CONNECT api.openai.com:443 - HIER_DIRECT/162.159.140.245 - ``` and confirmed the trace is sent successfully: <img width="878" height="75" alt="image" src="https://github.com/user-attachments/assets/0f76b8c0-82a9-410b-af4e-77364a9d7b70" /> ## Risks <!-- Note any risks associated with this change, or "None" if no risks --> No impact to non-`HTTPS_PROXY` setting usage so risk is pretty limited. ## Additional Notes <!-- Any other information that would be helpful for reviewers --> Co-authored-by: kyle <kyle@verhoog.ca> Co-authored-by: Yun Kim <35776586+Yun-Kim@users.noreply.github.com> Co-authored-by: Brett Langdon <brett.langdon@datadoghq.com>
1 parent 52b01a3 commit 6ba96f2

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

ddtrace/llmobs/_http.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import os
2+
import ssl
3+
from typing import Optional
4+
from urllib.parse import urlparse
5+
6+
from ddtrace.internal.http import HTTPConnection
7+
from ddtrace.internal.http import HTTPSConnection
8+
from ddtrace.internal.uds import UDSHTTPConnection
9+
from ddtrace.internal.utils.http import DEFAULT_TIMEOUT
10+
from ddtrace.internal.utils.http import ConnectionType
11+
from ddtrace.internal.utils.http import verify_url
12+
13+
14+
class ProxiedHTTPSConnection(HTTPSConnection):
15+
"""
16+
The built-in http.client in Python doesn't respect HTTPS_PROXY (even tho other clients like requests and curl do).
17+
18+
This implementation simply extends the client with support for basic proxies.
19+
"""
20+
21+
def __init__(
22+
self, host: str, port: Optional[int] = None, context: Optional[ssl.SSLContext] = None, **kwargs
23+
) -> None:
24+
if "HTTPS_PROXY" in os.environ:
25+
tunnel_port = port or 443
26+
proxy = urlparse(os.environ["HTTPS_PROXY"])
27+
proxy_host = proxy.hostname or ""
28+
# Default to 3128 (Squid's default port, de facto standard for HTTP proxies)
29+
proxy_port = proxy.port or 3128
30+
super().__init__(proxy_host, proxy_port, **kwargs)
31+
self.set_tunnel(host, tunnel_port)
32+
else:
33+
super().__init__(host, port, **kwargs)
34+
35+
36+
def get_connection(url: str, timeout: float = DEFAULT_TIMEOUT) -> ConnectionType:
37+
"""Return an HTTP connection to the given URL."""
38+
parsed = verify_url(url)
39+
hostname = parsed.hostname or ""
40+
path = parsed.path or "/"
41+
42+
if parsed.scheme == "https":
43+
return ProxiedHTTPSConnection.with_base_path(hostname, parsed.port, base_path=path, timeout=timeout)
44+
elif parsed.scheme == "http":
45+
return HTTPConnection.with_base_path(hostname, parsed.port, base_path=path, timeout=timeout)
46+
elif parsed.scheme == "unix":
47+
return UDSHTTPConnection(path, hostname, parsed.port, timeout=timeout)
48+
49+
raise ValueError("Unsupported protocol '%s'" % parsed.scheme)

ddtrace/llmobs/_writer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
from ddtrace.internal.logger import get_logger
2727
from ddtrace.internal.periodic import PeriodicService
2828
from ddtrace.internal.utils.http import Response
29-
from ddtrace.internal.utils.http import get_connection
3029
from ddtrace.internal.utils.retry import fibonacci_backoff_with_jitter
3130
from ddtrace.llmobs import _telemetry as telemetry
3231
from ddtrace.llmobs._constants import AGENTLESS_EVAL_BASE_URL
@@ -45,6 +44,7 @@
4544
from ddtrace.llmobs._experiment import JSONType
4645
from ddtrace.llmobs._experiment import Project
4746
from ddtrace.llmobs._experiment import UpdatableDatasetRecord
47+
from ddtrace.llmobs._http import get_connection
4848
from ddtrace.llmobs._utils import safe_json
4949
from ddtrace.llmobs.types import _Meta
5050
from ddtrace.llmobs.types import _SpanLink
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
fixes:
3+
- |
4+
LLM Observability: add support for HTTPS_PROXY.

0 commit comments

Comments
 (0)