From 17faea96bb75be88f6761398e3ad2130a0d29cfc Mon Sep 17 00:00:00 2001 From: Jonathan Yang Date: Wed, 3 Dec 2025 07:09:57 +0100 Subject: [PATCH] fix: conditionally pass enable_cleanup_closed to aiohttp TCPConnector (#17367) * fix: conditionally pass enable_cleanup_closed to aiohttp TCPConnector Fixes deprecation warning on Python 3.12.7+ and 3.13.1+ where enable_cleanup_closed is no longer needed since the underlying CPython SSL connection leak bug was fixed. See: https://github.com/python/cpython/pull/118960 * chore: add aiohttp source reference to AIOHTTP_NEEDS_CLEANUP_CLOSED --- litellm/constants.py | 7 +++++++ litellm/llms/custom_httpx/http_handler.py | 3 ++- litellm/proxy/proxy_server.py | 3 ++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/litellm/constants.py b/litellm/constants.py index 6a67a9a0e18..db617a2e475 100644 --- a/litellm/constants.py +++ b/litellm/constants.py @@ -1,4 +1,5 @@ import os +import sys from typing import List, Literal DEFAULT_HEALTH_CHECK_PROMPT = str( @@ -103,6 +104,12 @@ _DEFAULT_TTL_FOR_HTTPX_CLIENTS = 3600 # 1 hour, re-use the same httpx client fo AIOHTTP_CONNECTOR_LIMIT = int(os.getenv("AIOHTTP_CONNECTOR_LIMIT", 0)) AIOHTTP_KEEPALIVE_TIMEOUT = int(os.getenv("AIOHTTP_KEEPALIVE_TIMEOUT", 120)) AIOHTTP_TTL_DNS_CACHE = int(os.getenv("AIOHTTP_TTL_DNS_CACHE", 300)) +# enable_cleanup_closed is only needed for Python versions with the SSL leak bug +# Fixed in Python 3.12.7+ and 3.13.1+ (see https://github.com/python/cpython/pull/118960) +# Reference: https://github.com/aio-libs/aiohttp/blob/master/aiohttp/connector.py#L74-L78 +AIOHTTP_NEEDS_CLEANUP_CLOSED = ( + (3, 13, 0) <= sys.version_info < (3, 13, 1) or sys.version_info < (3, 12, 7) +) # WebSocket constants # Default to None (unlimited) to match OpenAI's official agents SDK behavior diff --git a/litellm/llms/custom_httpx/http_handler.py b/litellm/llms/custom_httpx/http_handler.py index c35e910ab08..b06e8463abd 100644 --- a/litellm/llms/custom_httpx/http_handler.py +++ b/litellm/llms/custom_httpx/http_handler.py @@ -17,6 +17,7 @@ from litellm.constants import ( _DEFAULT_TTL_FOR_HTTPX_CLIENTS, AIOHTTP_CONNECTOR_LIMIT, AIOHTTP_KEEPALIVE_TIMEOUT, + AIOHTTP_NEEDS_CLEANUP_CLOSED, AIOHTTP_TTL_DNS_CACHE, DEFAULT_SSL_CIPHERS, ) @@ -798,7 +799,7 @@ class AsyncHTTPHandler: limit=AIOHTTP_CONNECTOR_LIMIT, keepalive_timeout=AIOHTTP_KEEPALIVE_TIMEOUT, ttl_dns_cache=AIOHTTP_TTL_DNS_CACHE, - enable_cleanup_closed=True, + enable_cleanup_closed=AIOHTTP_NEEDS_CLEANUP_CLOSED, **connector_kwargs, ), trust_env=trust_env, diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 99789162318..a1e01caddc1 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -32,6 +32,7 @@ from litellm._uuid import uuid from litellm.constants import ( AIOHTTP_CONNECTOR_LIMIT, AIOHTTP_KEEPALIVE_TIMEOUT, + AIOHTTP_NEEDS_CLEANUP_CLOSED, AIOHTTP_TTL_DNS_CACHE, AUDIO_SPEECH_CHUNK_SIZE, BASE_MCP_ROUTE, @@ -635,7 +636,7 @@ async def _initialize_shared_aiohttp_session(): limit=AIOHTTP_CONNECTOR_LIMIT, keepalive_timeout=AIOHTTP_KEEPALIVE_TIMEOUT, ttl_dns_cache=AIOHTTP_TTL_DNS_CACHE, - enable_cleanup_closed=True, + enable_cleanup_closed=AIOHTTP_NEEDS_CLEANUP_CLOSED, ) session = ClientSession(connector=connector)