1818
1919import functools
2020import http .client as http_client
21+ import importlib .util
2122import logging
2223import numbers
2324import time
24- from typing import Optional
25-
26- try :
27- import requests
28- except ImportError as caught_exc : # pragma: NO COVER
25+ from typing import Optional , Set , TYPE_CHECKING
26+
27+ # PEP 0810: Explicit Lazy Imports
28+ # Python 3.15+ natively intercepts and defers these imports.
29+ # Developers can disable this behavior and force eager imports.
30+ # For more information, see:
31+ # https://docs.python.org/3.15/library/sys.html#sys.set_lazy_imports_filter
32+ # Older Python versions safely ignore this variable.
33+ __lazy_modules__ : Set [str ] = {
34+ "requests" ,
35+ "requests.adapters" ,
36+ "requests.exceptions" ,
37+ "requests.packages" ,
38+ "requests.packages.urllib3" ,
39+ "requests.packages.urllib3.util" ,
40+ "requests.packages.urllib3.util.ssl_" ,
41+ }
42+
43+
44+ if importlib .util .find_spec ("requests" ) is None :
2945 raise ImportError (
30- "The requests library is not installed from please install the requests package to use the requests transport."
31- ) from caught_exc
46+ "The requests library is not installed, please install the requests package to use the requests transport."
47+ )
48+
49+ import requests
3250import requests .adapters # pylint: disable=ungrouped-imports
3351import requests .exceptions # pylint: disable=ungrouped-imports
3452from requests .packages .urllib3 .util .ssl_ import ( # type: ignore
3553 create_urllib3_context ,
3654) # pylint: disable=ungrouped-imports
3755
38- from google .auth import _helpers
39- from google .auth import exceptions
40- from google .auth import transport
56+ from google .auth import _helpers , exceptions , transport
4157from google .auth .transport import _mtls_helper
4258import google .auth .transport ._mtls_helper
4359from google .oauth2 import service_account
4460
61+ if TYPE_CHECKING :
62+ _HTTPAdapterBase = requests .adapters .HTTPAdapter
63+ _SessionBase = requests .Session
64+ else :
65+ _HTTPAdapterBase = _helpers .HeapDummy
66+ _SessionBase = _helpers .HeapDummy
67+
68+
69+ class _LazyBasesMeta (_helpers .LazyBasesMeta ):
70+ def _perform_resolve_bases (cls ):
71+ current_bases = type .__getattribute__ (cls , "__bases__" )
72+ if current_bases == (_helpers .HeapDummy ,):
73+ cls_name = type .__getattribute__ (cls , "__name__" )
74+ if cls_name in ("_MutualTlsAdapter" , "_MutualTlsOffloadAdapter" ):
75+ cls .__bases__ = (requests .adapters .HTTPAdapter ,)
76+ elif cls_name == "AuthorizedSession" :
77+ cls .__bases__ = (requests .Session ,)
78+
79+
4580_LOGGER = logging .getLogger (__name__ )
4681
4782_DEFAULT_TIMEOUT = 120 # in seconds
@@ -84,9 +119,11 @@ class TimeoutGuard(object):
84119 :class:`requests.exceptions.Timeout`.
85120 """
86121
87- def __init__ (self , timeout , timeout_error_type = requests . exceptions . Timeout ):
122+ def __init__ (self , timeout , timeout_error_type = None ):
88123 self ._timeout = timeout
89124 self .remaining_timeout = timeout
125+ if timeout_error_type is None :
126+ timeout_error_type = requests .exceptions .Timeout
90127 self ._timeout_error_type = timeout_error_type
91128
92129 def __enter__ (self ):
@@ -161,7 +198,7 @@ def __call__(
161198 body = None ,
162199 headers = None ,
163200 timeout = _DEFAULT_TIMEOUT ,
164- ** kwargs
201+ ** kwargs ,
165202 ):
166203 """Make an HTTP request using requests.
167204
@@ -195,7 +232,7 @@ def __call__(
195232 raise new_exc from caught_exc
196233
197234
198- class _MutualTlsAdapter (requests . adapters . HTTPAdapter ):
235+ class _MutualTlsAdapter (_HTTPAdapterBase , metaclass = _LazyBasesMeta ):
199236 """
200237 A TransportAdapter that enables mutual TLS.
201238
@@ -209,9 +246,10 @@ class _MutualTlsAdapter(requests.adapters.HTTPAdapter):
209246 """
210247
211248 def __init__ (self , cert , key ):
212- import certifi
213249 import ssl
214250
251+ import certifi
252+
215253 ctx_poolmanager = create_urllib3_context ()
216254 ctx_poolmanager .load_verify_locations (cafile = certifi .where ())
217255
@@ -261,7 +299,7 @@ def proxy_manager_for(self, *args, **kwargs):
261299 return super (_MutualTlsAdapter , self ).proxy_manager_for (* args , ** kwargs )
262300
263301
264- class _MutualTlsOffloadAdapter (requests . adapters . HTTPAdapter ):
302+ class _MutualTlsOffloadAdapter (_HTTPAdapterBase , metaclass = _LazyBasesMeta ):
265303 """
266304 A TransportAdapter that enables mutual TLS and offloads the client side
267305 signing operation to the signing library.
@@ -285,6 +323,7 @@ class _MutualTlsOffloadAdapter(requests.adapters.HTTPAdapter):
285323
286324 def __init__ (self , enterprise_cert_file_path ):
287325 import certifi
326+
288327 from google .auth .transport import _custom_tls_signer
289328
290329 self .signer = _custom_tls_signer .CustomTlsSigner (enterprise_cert_file_path )
@@ -311,7 +350,7 @@ def proxy_manager_for(self, *args, **kwargs):
311350 return super (_MutualTlsOffloadAdapter , self ).proxy_manager_for (* args , ** kwargs )
312351
313352
314- class AuthorizedSession (requests . Session ):
353+ class AuthorizedSession (_SessionBase , metaclass = _LazyBasesMeta ):
315354 """A Requests Session class with credentials.
316355
317356 This class is used to perform requests to API endpoints that require
@@ -504,7 +543,7 @@ def request(
504543 headers = None ,
505544 max_allowed_time = None ,
506545 timeout = _DEFAULT_TIMEOUT ,
507- ** kwargs
546+ ** kwargs ,
508547 ):
509548 """Implementation of Requests' request.
510549
@@ -566,7 +605,7 @@ def request(
566605 data = data ,
567606 headers = request_headers ,
568607 timeout = timeout ,
569- ** kwargs
608+ ** kwargs ,
570609 )
571610 remaining_time = guard .remaining_timeout
572611
@@ -638,7 +677,7 @@ def request(
638677 max_allowed_time = remaining_time ,
639678 timeout = timeout ,
640679 _credential_refresh_attempt = _credential_refresh_attempt + 1 ,
641- ** kwargs
680+ ** kwargs ,
642681 )
643682
644683 return response
0 commit comments