|
5 | 5 | #
|
6 | 6 | import contextvars
|
7 | 7 | import threading
|
| 8 | +from functools import cache |
8 | 9 | from json.decoder import JSONDecodeError
|
9 | 10 | from typing import Union
|
10 | 11 |
|
11 | 12 | import httpx
|
12 | 13 | import requests
|
| 14 | +from httpx._config import Proxy |
| 15 | +from httpx._utils import get_environment_proxies |
13 | 16 | from requests.adapters import HTTPAdapter
|
14 | 17 |
|
15 | 18 | from connect.client.constants import CONNECT_ENDPOINT_URL, CONNECT_SPECS_URL
|
@@ -237,6 +240,20 @@ def _get_namespace_class(self):
|
237 | 240 | _SSL_CONTEXT = httpx.create_ssl_context()
|
238 | 241 |
|
239 | 242 |
|
| 243 | +@cache |
| 244 | +def _get_async_mounts(): |
| 245 | + """ |
| 246 | + This code based on how httpx.Client mounts proxies from environment. |
| 247 | + This is cached to allow reusing the created transport objects. |
| 248 | + """ |
| 249 | + return { |
| 250 | + key: None |
| 251 | + if url is None |
| 252 | + else httpx.AsyncHTTPTransport(verify=_SSL_CONTEXT, proxy=Proxy(url=url)) |
| 253 | + for key, url in get_environment_proxies().items() |
| 254 | + } |
| 255 | + |
| 256 | + |
240 | 257 | class AsyncConnectClient(_ConnectClientBase, AsyncClientMixin):
|
241 | 258 | """
|
242 | 259 | Create a new instance of the AsyncConnectClient.
|
@@ -274,12 +291,14 @@ def __init__(self, *args, **kwargs):
|
274 | 291 | def session(self):
|
275 | 292 | value = self._session.get()
|
276 | 293 | if not value:
|
277 |
| - value = httpx.AsyncClient( |
278 |
| - transport=_ASYNC_TRANSPORTS.setdefault( |
279 |
| - self.endpoint, |
280 |
| - httpx.AsyncHTTPTransport(verify=_SSL_CONTEXT), |
281 |
| - ), |
282 |
| - ) |
| 294 | + transport = _ASYNC_TRANSPORTS.get(self.endpoint) |
| 295 | + if not transport: |
| 296 | + transport = _ASYNC_TRANSPORTS[self.endpoint] = httpx.AsyncHTTPTransport( |
| 297 | + verify=_SSL_CONTEXT, |
| 298 | + ) |
| 299 | + # When passing a transport to httpx a Client/AsyncClient, proxies defined in environment |
| 300 | + # (like HTTP_PROXY) are ignored, so let's pass them using mounts parameter. |
| 301 | + value = httpx.AsyncClient(transport=transport, mounts=_get_async_mounts()) |
283 | 302 | self._session.set(value)
|
284 | 303 | return value
|
285 | 304 |
|
|
0 commit comments