From 22ff3da3cf27bec4e9cf65bce94c3de79f889506 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Thu, 26 Jun 2025 08:37:22 -0700 Subject: [PATCH] [Fix] Allow using HTTP_ Proxy settings with trust_env (#12066) * allow using trust_env * add docs on how to use HTTP_PROXY * docs AIOHTTP_TRUST_ENV * test_aiohttp_transport_trust_env_setting * docs fix --- .../docs/guides/security_settings.md | 31 +++++++++++++++++-- docs/my-website/docs/proxy/config_settings.md | 1 + litellm/__init__.py | 1 + litellm/llms/custom_httpx/http_handler.py | 11 ++++++- .../llms/custom_httpx/test_http_handler.py | 28 +++++++++++++++++ 5 files changed, 68 insertions(+), 4 deletions(-) diff --git a/docs/my-website/docs/guides/security_settings.md b/docs/my-website/docs/guides/security_settings.md index 4dfeda2d70..008e620c51 100644 --- a/docs/my-website/docs/guides/security_settings.md +++ b/docs/my-website/docs/guides/security_settings.md @@ -1,14 +1,14 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -# SSL Security Settings +# SSL, HTTP Proxy Security Settings If you're in an environment using an older TTS bundle, with an older encryption, follow this guide. LiteLLM uses HTTPX for network requests, unless otherwise specified. -1. Disable SSL verification +## 1. Disable SSL verification @@ -35,7 +35,7 @@ export SSL_VERIFY="False" -2. Lower security settings +## 2. Lower security settings @@ -63,4 +63,29 @@ export SSL_CERTIFICATE="/path/to/certificate.pem" +## 3. Use HTTP_PROXY environment variable + +Both httpx and aiohttp libraries use `urllib.request.getproxies` from environment variables. Before client initialization, you may set proxy (and optional SSL_CERT_FILE) by setting the environment variables: + + + + +```python +import litellm +litellm.aiohttp_trust_env = True +``` + +```bash +export HTTPS_PROXY='http://username:password@proxy_uri:port' +``` + + + + +```bash +export HTTPS_PROXY='http://username:password@proxy_uri:port' +export AIOHTTP_TRUST_ENV='True' +``` + + diff --git a/docs/my-website/docs/proxy/config_settings.md b/docs/my-website/docs/proxy/config_settings.md index ce9a938078..37efe0fc33 100644 --- a/docs/my-website/docs/proxy/config_settings.md +++ b/docs/my-website/docs/proxy/config_settings.md @@ -307,6 +307,7 @@ router_settings: | AGENTOPS_SERVICE_NAME | Service Name for AgentOps logging integration | AISPEND_ACCOUNT_ID | Account ID for AI Spend | AISPEND_API_KEY | API Key for AI Spend +| AIOHTTP_TRUST_ENV | Flag to enable aiohttp trust environment. When this is set to True, aiohttp will respect HTTP(S)_PROXY env vars. **Default is False** | ALLOWED_EMAIL_DOMAINS | List of email domains allowed for access | ARIZE_API_KEY | API key for Arize platform integration | ARIZE_SPACE_KEY | Space key for Arize platform diff --git a/litellm/__init__.py b/litellm/__init__.py index c2064d5d57..1ba7d663d8 100644 --- a/litellm/__init__.py +++ b/litellm/__init__.py @@ -323,6 +323,7 @@ priority_reservation: Optional[Dict[str, float]] = None use_aiohttp_transport: bool = ( True # Older variable, aiohttp is now the default. use disable_aiohttp_transport instead. ) +aiohttp_trust_env: bool = False # set to true to use HTTP_ Proxy settings disable_aiohttp_transport: bool = False # Set this to true to use httpx instead disable_aiohttp_trust_env: bool = False # When False, aiohttp will respect HTTP(S)_PROXY env vars force_ipv4: bool = ( diff --git a/litellm/llms/custom_httpx/http_handler.py b/litellm/llms/custom_httpx/http_handler.py index 1d68702d2e..34968a63ae 100644 --- a/litellm/llms/custom_httpx/http_handler.py +++ b/litellm/llms/custom_httpx/http_handler.py @@ -580,15 +580,24 @@ class AsyncHTTPHandler: - True: use default SSL verification (equivalent to ssl.create_default_context()) """ from litellm.llms.custom_httpx.aiohttp_transport import LiteLLMAiohttpTransport + from litellm.secret_managers.main import str_to_bool connector_kwargs = AsyncHTTPHandler._get_ssl_connector_kwargs( ssl_verify=ssl_verify, ssl_context=ssl_context ) + ######################################################### + # Check if user enabled aiohttp trust env + # use for HTTP_PROXY, HTTPS_PROXY, etc. + ######################################################## + trust_env: bool = litellm.aiohttp_trust_env + if str_to_bool(os.getenv("AIOHTTP_TRUST_ENV", "False")) is True: + trust_env = True verbose_logger.debug("Creating AiohttpTransport...") return LiteLLMAiohttpTransport( client=lambda: ClientSession( - connector=TCPConnector(**connector_kwargs) + connector=TCPConnector(**connector_kwargs), + trust_env=trust_env, ), ) diff --git a/tests/test_litellm/llms/custom_httpx/test_http_handler.py b/tests/test_litellm/llms/custom_httpx/test_http_handler.py index bc960fdc22..6f66bf20a0 100644 --- a/tests/test_litellm/llms/custom_httpx/test_http_handler.py +++ b/tests/test_litellm/llms/custom_httpx/test_http_handler.py @@ -123,6 +123,34 @@ async def test_ssl_verification_with_aiohttp_transport(): assert transport_connector._ssl == aiohttp_session.connector._ssl +@pytest.mark.asyncio +async def test_aiohttp_transport_trust_env_setting(monkeypatch): + """Test that trust_env setting is properly configured in aiohttp transport""" + # Test 1: Default trust_env behavior + transport = AsyncHTTPHandler._create_aiohttp_transport() + client_session = transport._get_valid_client_session() + + # Default should be False (litellm.aiohttp_trust_env default) + default_trust_env = getattr(litellm, 'aiohttp_trust_env', False) + assert client_session._trust_env == default_trust_env + + # Test 2: Environment variable override + monkeypatch.setenv("AIOHTTP_TRUST_ENV", "True") + transport_with_env = AsyncHTTPHandler._create_aiohttp_transport() + client_session_with_env = transport_with_env._get_valid_client_session() + + # Should be True when environment variable is set + assert client_session_with_env._trust_env is True + + # Test 3: Verify environment variable with False value + monkeypatch.setenv("AIOHTTP_TRUST_ENV", "False") + transport_with_false_env = AsyncHTTPHandler._create_aiohttp_transport() + client_session_with_false_env = transport_with_false_env._get_valid_client_session() + + # Should respect the litellm.aiohttp_trust_env setting when env var is False + assert client_session_with_false_env._trust_env == default_trust_env + + def test_get_ssl_context(): """Test that _get_ssl_context() returns a proper SSL context with certifi CA bundle""" with patch('ssl.create_default_context') as mock_create_context: