From dfae508200e4180ab9504bd3bddcc161f42384b0 Mon Sep 17 00:00:00 2001 From: harish876 Date: Fri, 10 Apr 2026 00:41:40 +0000 Subject: [PATCH] - standalone script to test aiohttp client with timeout and without timeout - debug logs to view timeout values --- litellm/llms/azure/common_utils.py | 3 ++ .../llms/custom_httpx/aiohttp_transport.py | 1 + scripts/test_aiohttp_timeout.py | 54 +++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 scripts/test_aiohttp_timeout.py diff --git a/litellm/llms/azure/common_utils.py b/litellm/llms/azure/common_utils.py index 4fc1ae960b8..467fdb9a0b5 100644 --- a/litellm/llms/azure/common_utils.py +++ b/litellm/llms/azure/common_utils.py @@ -553,6 +553,9 @@ class BaseAzureLLM(BaseOpenAILLM): max_retries = litellm_params.get("max_retries") timeout = litellm_params.get("timeout") + verbose_logger.debug( + "Azure initialize_azure_sdk_client litellm_params timeout=%s", timeout + ) if ( not api_key and azure_ad_token_provider is None diff --git a/litellm/llms/custom_httpx/aiohttp_transport.py b/litellm/llms/custom_httpx/aiohttp_transport.py index 132191c946c..b191ea22f1e 100644 --- a/litellm/llms/custom_httpx/aiohttp_transport.py +++ b/litellm/llms/custom_httpx/aiohttp_transport.py @@ -292,6 +292,7 @@ class LiteLLMAiohttpTransport(AiohttpTransport): ) -> httpx.Response: timeout = request.extensions.get("timeout", {}) sni_hostname = request.extensions.get("sni_hostname") + verbose_logger.debug("AiohttpTransport.handle_async_request timeout=%s", timeout) # Use helper to ensure we have a valid session for the current event loop client_session = self._get_valid_client_session() diff --git a/scripts/test_aiohttp_timeout.py b/scripts/test_aiohttp_timeout.py new file mode 100644 index 00000000000..134743b2b40 --- /dev/null +++ b/scripts/test_aiohttp_timeout.py @@ -0,0 +1,54 @@ +import argparse +import asyncio +import time + +import aiohttp +import httpx + +from litellm.llms.custom_httpx.aiohttp_transport import LiteLLMAiohttpTransport + + +async def main() -> None: + parser = argparse.ArgumentParser( + description="Single httpbin delay test for LiteLLM aiohttp transport timeouts." + ) + parser.add_argument("--delay-seconds", type=int, default=5) + parser.add_argument("--timeout-seconds", type=float, default=2.0) + parser.add_argument("--pass-timeout", type=bool, default=False) + args = parser.parse_args() + + url = f"https://httpbin.org/delay/{args.delay_seconds}" + timeout = httpx.Timeout(args.timeout_seconds) + transport = LiteLLMAiohttpTransport( + client=lambda: aiohttp.ClientSession(trust_env=True) + ) + + print(f"url={url}") + print(f"timeout={args.timeout_seconds}s") + + started_at = time.perf_counter() + try: + request = httpx.Request( + method="GET", + url=url, + extensions={"timeout": timeout.as_dict() if args.pass_timeout else {}}, + ) + print(timeout.as_dict() if args.pass_timeout else {}) + print(f"request.extensions['timeout']={request.extensions.get('timeout')}") + + response = await transport.handle_async_request(request) + + elapsed = time.perf_counter() - started_at + print(f"SUCCESS status_code={response.status_code} elapsed_s={elapsed:.2f}") + print("If elapsed is much greater than timeout, timeout is not respected.") + except Exception as e: + elapsed = time.perf_counter() - started_at + print( + f"EXCEPTION type={type(e).__name__} elapsed_s={elapsed:.2f} detail={e}" + ) + finally: + await transport.aclose() + + +if __name__ == "__main__": + asyncio.run(main())