Files
litellm/tests/litellm_utils_tests/test_aiohttp_handler.py
T
Ishaan Jaff 86cdb8382b [Feat] Use aiohttp transport by default - 97% lower median latency (#11097)
* fix: add flag for disabling use_aiohttp_transport

* feat: add _create_async_transport

* feat: fixes for transport

* add httpx-aiohttp

* feat: fixes for transport

* refactor: fixes for transport

* build: fix deps

* fixes: test fixes

* fix: ensure aiohttp does not auto set content type

* test: test fixes

* feat: add LiteLLMAiohttpTransport

* fix: fixes for responses API handling

* test: fixes for responses API handling

* test: fixes for responses API handling

* feat: fixes for transport

* fix: base embedding handler

* test: test_async_http_handler_force_ipv4

* test: fix failing deepeval test

* fix: add YARL for bedrock urls

* fix: issues with transport

* fix: comment out linting issues

* test fix

* test: XAI is unstable

* test: fixes for using respx

* test: XAI fixes

* test: XAI fixes

* test: infinity testing fixes

* docs(config_settings.md): document param

* test: test_openai_image_edit_litellm_sdk

* test: remove deprecated test

* bump respx==0.22.0

* test: test_xai_message_name_filtering

* test: fix anthropic test after bumping httpx

* use n 4 for mapped tests (#11109)

* fix: use 1 session per event loop

* test: test_client_session_helper

* fix: linting error

* fix: resolving GET requests on httpx 0.28.1

* test fixes proxy unit tests

* fix: add ssl verify settings

* fix: proxy unit tests

* fix: refactor

* tests: basic unit tests for aiohttp transports

* tests: fixes xai

---------

Co-authored-by: Krrish Dholakia <krrishdholakia@gmail.com>
2025-05-23 22:55:35 -07:00

124 lines
4.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import asyncio
import copy
import sys
import time
from datetime import datetime
from unittest import mock
from dotenv import load_dotenv
from litellm.types.utils import StandardCallbackDynamicParams
load_dotenv()
import os
sys.path.insert(
0, os.path.abspath("../..")
) # Adds the parent directory to the system-path
import pytest
import litellm
from litellm.llms.custom_httpx.http_handler import AsyncHTTPHandler
@pytest.mark.asyncio
async def test_client_session_helper():
"""Test that the client session helper handles event loop changes correctly"""
try:
# Create a transport with the new helper
transport = AsyncHTTPHandler._create_aiohttp_transport()
if transport is not None:
print('✅ Successfully created aiohttp transport with helper')
# Test the helper function directly if it's a LiteLLMAiohttpTransport
if hasattr(transport, '_get_valid_client_session'):
session1 = transport._get_valid_client_session() # type: ignore
print(f'✅ First session created: {type(session1).__name__}')
# Call it again to test reuse
session2 = transport._get_valid_client_session() # type: ignore
print(f'✅ Second session call: {type(session2).__name__}')
# In the same event loop, should be the same session
print(f'✅ Same session reused: {session1 is session2}')
return True
else:
print('️ No aiohttp transport available (probably missing httpx-aiohttp)')
return True
except Exception as e:
print(f'❌ Error: {e}')
import traceback
traceback.print_exc()
return False
async def test_event_loop_robustness():
"""Test behavior when event loops change (simulating CI/CD scenario)"""
try:
# Test session creation in multiple scenarios
transport = AsyncHTTPHandler._create_aiohttp_transport()
if transport and hasattr(transport, '_get_valid_client_session'):
# Test 1: Normal usage
session = transport._get_valid_client_session() # type: ignore
print(f'✅ Normal session creation works: {session is not None}')
# Test 2: Force recreation by setting client to a callable
from aiohttp import ClientSession
transport.client = lambda: ClientSession() # type: ignore
session2 = transport._get_valid_client_session() # type: ignore
print(f'✅ Session recreation after callable works: {session2 is not None}')
return True
else:
print('️ Transport not available or no helper method')
return True
except Exception as e:
print(f'❌ Error in event loop robustness test: {e}')
import traceback
traceback.print_exc()
return False
async def test_httpx_request_simulation():
"""Test that the transport can handle a simulated HTTP request"""
try:
transport = AsyncHTTPHandler._create_aiohttp_transport()
if transport is not None:
print('✅ Transport created for request simulation')
# Create a simple httpx request to test with
import httpx
request = httpx.Request('GET', 'https://httpbin.org/headers')
# Just test that we can get a valid session for this request context
if hasattr(transport, '_get_valid_client_session'):
session = transport._get_valid_client_session() # type: ignore
print(f'✅ Got valid session for request: {session is not None}')
# Test that session has required aiohttp methods
has_request_method = hasattr(session, 'request')
print(f'✅ Session has request method: {has_request_method}')
return has_request_method
return True
else:
print('️ No transport available for request simulation')
return True
except Exception as e:
print(f'❌ Error in request simulation: {e}')
return False
if __name__ == "__main__":
print("Testing client session helper and event loop handling fix...")
result1 = asyncio.run(test_client_session_helper())
result2 = asyncio.run(test_event_loop_robustness())
result3 = asyncio.run(test_httpx_request_simulation())
if result1 and result2 and result3:
print("🎉 All tests passed! The helper function approach should fix the CI/CD event loop issues.")
else:
print("💥 Some tests failed")