2525from dataclasses import dataclass
2626import datetime
2727import http
28+ import inspect
2829import io
2930import json
3031import logging
3435import sys
3536import threading
3637import time
37- from typing import Any , AsyncIterator , Optional , Tuple , TYPE_CHECKING , Union
38+ from typing import Any , AsyncIterator , Optional , TYPE_CHECKING , Tuple , Union
3839from urllib .parse import urlparse
3940from urllib .parse import urlunparse
4041
@@ -509,6 +510,11 @@ def __init__(
509510 )
510511 self ._httpx_client = SyncHttpxClient (** client_args )
511512 self ._async_httpx_client = AsyncHttpxClient (** async_client_args )
513+ if has_aiohttp :
514+ # Do it once at the genai.Client level. Share among all requests.
515+ self ._async_client_session_request_args = self ._ensure_aiohttp_ssl_ctx (
516+ self ._http_options
517+ )
512518
513519 @staticmethod
514520 def _ensure_httpx_ssl_ctx (
@@ -561,7 +567,12 @@ def _maybe_set(
561567 if not args or not args .get (verify ):
562568 args = (args or {}).copy ()
563569 args [verify ] = ctx
564- return args
570+ # Drop the args that isn't used by the httpx client.
571+ copied_args = args .copy ()
572+ for key in copied_args .copy ():
573+ if key not in inspect .signature (httpx .Client .__init__ ).parameters :
574+ del copied_args [key ]
575+ return copied_args
565576
566577 return (
567578 _maybe_set (args , ctx ),
@@ -581,7 +592,7 @@ def _ensure_aiohttp_ssl_ctx(options: HttpOptions) -> dict[str, Any]:
581592 An async aiohttp ClientSession._request args.
582593 """
583594
584- verify = 'verify'
595+ verify = 'ssl' # keep it consistent with httpx.
585596 async_args = options .async_client_args
586597 ctx = async_args .get (verify ) if async_args else None
587598
@@ -613,10 +624,16 @@ def _maybe_set(
613624 """
614625 if not args or not args .get (verify ):
615626 args = (args or {}).copy ()
616- args ['ssl' ] = ctx
617- else :
618- args ['ssl' ] = args .pop (verify )
619- return args
627+ args [verify ] = ctx
628+ # Drop the args that isn't in the aiohttp RequestOptions.
629+ copied_args = args .copy ()
630+ for key in copied_args .copy ():
631+ if (
632+ key
633+ not in inspect .signature (aiohttp .ClientSession ._request ).parameters
634+ ):
635+ del copied_args [key ]
636+ return copied_args
620637
621638 return _maybe_set (async_args , ctx )
622639
@@ -819,30 +836,16 @@ async def _async_request(
819836 if has_aiohttp :
820837 session = aiohttp .ClientSession (
821838 headers = http_request .headers ,
839+ trust_env = True ,
840+ )
841+ response = await session .request (
842+ method = http_request .method ,
843+ url = http_request .url ,
844+ headers = http_request .headers ,
845+ data = data ,
846+ timeout = aiohttp .ClientTimeout (connect = http_request .timeout ),
847+ ** self ._async_client_session_request_args ,
822848 )
823- if self ._http_options .async_client_args :
824- # When using aiohttp request options with ssl context, the latency will higher than using httpx.
825- # Use it only if necessary. Otherwise, httpx asyncclient is faster.
826- async_client_args = self ._ensure_aiohttp_ssl_ctx (
827- self ._http_options
828- )
829- response = await session .request (
830- method = http_request .method ,
831- url = http_request .url ,
832- headers = http_request .headers ,
833- data = data ,
834- timeout = aiohttp .ClientTimeout (connect = http_request .timeout ),
835- ** async_client_args ,
836- )
837- else :
838- # Aiohttp performs better than httpx w/o ssl context.
839- response = await session .request (
840- method = http_request .method ,
841- url = http_request .url ,
842- headers = http_request .headers ,
843- data = data ,
844- timeout = aiohttp .ClientTimeout (connect = http_request .timeout ),
845- )
846849 await errors .APIError .raise_for_async_response (response )
847850 return HttpResponse (response .headers , response )
848851 else :
@@ -862,39 +865,20 @@ async def _async_request(
862865 return HttpResponse (client_response .headers , client_response )
863866 else :
864867 if has_aiohttp :
865- if self ._http_options .async_client_args :
866- # Note that when using aiohttp request options with ssl context, the
867- # latency will higher than using httpx async client with ssl context.
868- async_client_args = self ._ensure_aiohttp_ssl_ctx (
869- self ._http_options
868+ async with aiohttp .ClientSession (
869+ headers = http_request .headers ,
870+ trust_env = True ,
871+ ) as session :
872+ response = await session .request (
873+ method = http_request .method ,
874+ url = http_request .url ,
875+ headers = http_request .headers ,
876+ data = data ,
877+ timeout = aiohttp .ClientTimeout (connect = http_request .timeout ),
878+ ** self ._async_client_session_request_args ,
870879 )
871- async with aiohttp .ClientSession (
872- headers = http_request .headers
873- ) as session :
874- response = await session .request (
875- method = http_request .method ,
876- url = http_request .url ,
877- headers = http_request .headers ,
878- data = data ,
879- timeout = aiohttp .ClientTimeout (connect = http_request .timeout ),
880- ** async_client_args ,
881- )
882- await errors .APIError .raise_for_async_response (response )
883- return HttpResponse (response .headers , [await response .text ()])
884- else :
885- # Aiohttp performs better than httpx if not using ssl context.
886- async with aiohttp .ClientSession (
887- headers = http_request .headers
888- ) as session :
889- response = await session .request (
890- method = http_request .method ,
891- url = http_request .url ,
892- headers = http_request .headers ,
893- data = data ,
894- timeout = aiohttp .ClientTimeout (connect = http_request .timeout ),
895- )
896- await errors .APIError .raise_for_async_response (response )
897- return HttpResponse (response .headers , [await response .text ()])
880+ await errors .APIError .raise_for_async_response (response )
881+ return HttpResponse (response .headers , [await response .text ()])
898882 else :
899883 # aiohttp is not available. Fall back to httpx.
900884 client_response = await self ._async_httpx_client .request (
@@ -1192,7 +1176,8 @@ async def _async_upload_fd(
11921176 # Upload the file in chunks
11931177 if has_aiohttp : # pylint: disable=g-import-not-at-top
11941178 async with aiohttp .ClientSession (
1195- headers = self ._http_options .headers
1179+ headers = self ._http_options .headers ,
1180+ trust_env = True ,
11961181 ) as session :
11971182 while True :
11981183 if isinstance (file , io .IOBase ):
@@ -1367,7 +1352,10 @@ async def async_download_file(
13671352 data = http_request .data
13681353
13691354 if has_aiohttp :
1370- async with aiohttp .ClientSession (headers = http_request .headers ) as session :
1355+ async with aiohttp .ClientSession (
1356+ headers = http_request .headers ,
1357+ trust_env = True ,
1358+ ) as session :
13711359 response = await session .request (
13721360 method = http_request .method ,
13731361 url = http_request .url ,
0 commit comments