We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Set the default request timeout to something other than `None`
The [AuthorizedSession.requests()](https://github.com/googleapis/google-auth-library-python/blob/1b9de8dfbe4523f3170e47985ab523cb7865de48/google/auth/transport/requests.py#L242-L251) method does not specify a default timeout.

Since production code would almost always want to have some sort of a timeout, let's add one. The libraries that rely on `google-auth`, but do (yet) not specify a timeout themselves, would benefit from that.

Example: [storage issue](https://github.com/googleapis/google-cloud-python/issues/10182)


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `google/auth/transport/requests.py`
Content:
```
1 # Copyright 2016 Google Inc.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 """Transport adapter for Requests."""
16 
17 from __future__ import absolute_import
18 
19 import functools
20 import logging
21 import numbers
22 import time
23 
24 try:
25     import requests
26 except ImportError as caught_exc:  # pragma: NO COVER
27     import six
28 
29     six.raise_from(
30         ImportError(
31             "The requests library is not installed, please install the "
32             "requests package to use the requests transport."
33         ),
34         caught_exc,
35     )
36 import requests.adapters  # pylint: disable=ungrouped-imports
37 import requests.exceptions  # pylint: disable=ungrouped-imports
38 import six  # pylint: disable=ungrouped-imports
39 
40 from google.auth import exceptions
41 from google.auth import transport
42 
43 _LOGGER = logging.getLogger(__name__)
44 
45 
46 class _Response(transport.Response):
47     """Requests transport response adapter.
48 
49     Args:
50         response (requests.Response): The raw Requests response.
51     """
52 
53     def __init__(self, response):
54         self._response = response
55 
56     @property
57     def status(self):
58         return self._response.status_code
59 
60     @property
61     def headers(self):
62         return self._response.headers
63 
64     @property
65     def data(self):
66         return self._response.content
67 
68 
69 class TimeoutGuard(object):
70     """A context manager raising an error if the suite execution took too long.
71 
72     Args:
73         timeout ([Union[None, float, Tuple[float, float]]]):
74             The maximum number of seconds a suite can run without the context
75             manager raising a timeout exception on exit. If passed as a tuple,
76             the smaller of the values is taken as a timeout. If ``None``, a
77             timeout error is never raised.
78         timeout_error_type (Optional[Exception]):
79             The type of the error to raise on timeout. Defaults to
80             :class:`requests.exceptions.Timeout`.
81     """
82 
83     def __init__(self, timeout, timeout_error_type=requests.exceptions.Timeout):
84         self._timeout = timeout
85         self.remaining_timeout = timeout
86         self._timeout_error_type = timeout_error_type
87 
88     def __enter__(self):
89         self._start = time.time()
90         return self
91 
92     def __exit__(self, exc_type, exc_value, traceback):
93         if exc_value:
94             return  # let the error bubble up automatically
95 
96         if self._timeout is None:
97             return  # nothing to do, the timeout was not specified
98 
99         elapsed = time.time() - self._start
100         deadline_hit = False
101 
102         if isinstance(self._timeout, numbers.Number):
103             self.remaining_timeout = self._timeout - elapsed
104             deadline_hit = self.remaining_timeout <= 0
105         else:
106             self.remaining_timeout = tuple(x - elapsed for x in self._timeout)
107             deadline_hit = min(self.remaining_timeout) <= 0
108 
109         if deadline_hit:
110             raise self._timeout_error_type()
111 
112 
113 class Request(transport.Request):
114     """Requests request adapter.
115 
116     This class is used internally for making requests using various transports
117     in a consistent way. If you use :class:`AuthorizedSession` you do not need
118     to construct or use this class directly.
119 
120     This class can be useful if you want to manually refresh a
121     :class:`~google.auth.credentials.Credentials` instance::
122 
123         import google.auth.transport.requests
124         import requests
125 
126         request = google.auth.transport.requests.Request()
127 
128         credentials.refresh(request)
129 
130     Args:
131         session (requests.Session): An instance :class:`requests.Session` used
132             to make HTTP requests. If not specified, a session will be created.
133 
134     .. automethod:: __call__
135     """
136 
137     def __init__(self, session=None):
138         if not session:
139             session = requests.Session()
140 
141         self.session = session
142 
143     def __call__(
144         self, url, method="GET", body=None, headers=None, timeout=120, **kwargs
145     ):
146         """Make an HTTP request using requests.
147 
148         Args:
149             url (str): The URI to be requested.
150             method (str): The HTTP method to use for the request. Defaults
151                 to 'GET'.
152             body (bytes): The payload / body in HTTP request.
153             headers (Mapping[str, str]): Request headers.
154             timeout (Optional[int]): The number of seconds to wait for a
155                 response from the server. If not specified or if None, the
156                 requests default timeout will be used.
157             kwargs: Additional arguments passed through to the underlying
158                 requests :meth:`~requests.Session.request` method.
159 
160         Returns:
161             google.auth.transport.Response: The HTTP response.
162 
163         Raises:
164             google.auth.exceptions.TransportError: If any exception occurred.
165         """
166         try:
167             _LOGGER.debug("Making request: %s %s", method, url)
168             response = self.session.request(
169                 method, url, data=body, headers=headers, timeout=timeout, **kwargs
170             )
171             return _Response(response)
172         except requests.exceptions.RequestException as caught_exc:
173             new_exc = exceptions.TransportError(caught_exc)
174             six.raise_from(new_exc, caught_exc)
175 
176 
177 class AuthorizedSession(requests.Session):
178     """A Requests Session class with credentials.
179 
180     This class is used to perform requests to API endpoints that require
181     authorization::
182 
183         from google.auth.transport.requests import AuthorizedSession
184 
185         authed_session = AuthorizedSession(credentials)
186 
187         response = authed_session.request(
188             'GET', 'https://www.googleapis.com/storage/v1/b')
189 
190     The underlying :meth:`request` implementation handles adding the
191     credentials' headers to the request and refreshing credentials as needed.
192 
193     Args:
194         credentials (google.auth.credentials.Credentials): The credentials to
195             add to the request.
196         refresh_status_codes (Sequence[int]): Which HTTP status codes indicate
197             that credentials should be refreshed and the request should be
198             retried.
199         max_refresh_attempts (int): The maximum number of times to attempt to
200             refresh the credentials and retry the request.
201         refresh_timeout (Optional[int]): The timeout value in seconds for
202             credential refresh HTTP requests.
203         auth_request (google.auth.transport.requests.Request):
204             (Optional) An instance of
205             :class:`~google.auth.transport.requests.Request` used when
206             refreshing credentials. If not passed,
207             an instance of :class:`~google.auth.transport.requests.Request`
208             is created.
209     """
210 
211     def __init__(
212         self,
213         credentials,
214         refresh_status_codes=transport.DEFAULT_REFRESH_STATUS_CODES,
215         max_refresh_attempts=transport.DEFAULT_MAX_REFRESH_ATTEMPTS,
216         refresh_timeout=None,
217         auth_request=None,
218     ):
219         super(AuthorizedSession, self).__init__()
220         self.credentials = credentials
221         self._refresh_status_codes = refresh_status_codes
222         self._max_refresh_attempts = max_refresh_attempts
223         self._refresh_timeout = refresh_timeout
224 
225         if auth_request is None:
226             auth_request_session = requests.Session()
227 
228             # Using an adapter to make HTTP requests robust to network errors.
229             # This adapter retrys HTTP requests when network errors occur
230             # and the requests seems safely retryable.
231             retry_adapter = requests.adapters.HTTPAdapter(max_retries=3)
232             auth_request_session.mount("https://", retry_adapter)
233 
234             # Do not pass `self` as the session here, as it can lead to
235             # infinite recursion.
236             auth_request = Request(auth_request_session)
237 
238         # Request instance used by internal methods (for example,
239         # credentials.refresh).
240         self._auth_request = auth_request
241 
242     def request(
243         self,
244         method,
245         url,
246         data=None,
247         headers=None,
248         max_allowed_time=None,
249         timeout=None,
250         **kwargs
251     ):
252         """Implementation of Requests' request.
253 
254         Args:
255             timeout (Optional[Union[float, Tuple[float, float]]]):
256                 The amount of time in seconds to wait for the server response
257                 with each individual request.
258 
259                 Can also be passed as a tuple (connect_timeout, read_timeout).
260                 See :meth:`requests.Session.request` documentation for details.
261 
262             max_allowed_time (Optional[float]):
263                 If the method runs longer than this, a ``Timeout`` exception is
264                 automatically raised. Unlike the ``timeout` parameter, this
265                 value applies to the total method execution time, even if
266                 multiple requests are made under the hood.
267 
268                 Mind that it is not guaranteed that the timeout error is raised
269                 at ``max_allowed_time`. It might take longer, for example, if
270                 an underlying request takes a lot of time, but the request
271                 itself does not timeout, e.g. if a large file is being
272                 transmitted. The timout error will be raised after such
273                 request completes.
274         """
275         # pylint: disable=arguments-differ
276         # Requests has a ton of arguments to request, but only two
277         # (method, url) are required. We pass through all of the other
278         # arguments to super, so no need to exhaustively list them here.
279 
280         # Use a kwarg for this instead of an attribute to maintain
281         # thread-safety.
282         _credential_refresh_attempt = kwargs.pop("_credential_refresh_attempt", 0)
283 
284         # Make a copy of the headers. They will be modified by the credentials
285         # and we want to pass the original headers if we recurse.
286         request_headers = headers.copy() if headers is not None else {}
287 
288         # Do not apply the timeout unconditionally in order to not override the
289         # _auth_request's default timeout.
290         auth_request = (
291             self._auth_request
292             if timeout is None
293             else functools.partial(self._auth_request, timeout=timeout)
294         )
295 
296         remaining_time = max_allowed_time
297 
298         with TimeoutGuard(remaining_time) as guard:
299             self.credentials.before_request(auth_request, method, url, request_headers)
300         remaining_time = guard.remaining_timeout
301 
302         with TimeoutGuard(remaining_time) as guard:
303             response = super(AuthorizedSession, self).request(
304                 method,
305                 url,
306                 data=data,
307                 headers=request_headers,
308                 timeout=timeout,
309                 **kwargs
310             )
311         remaining_time = guard.remaining_timeout
312 
313         # If the response indicated that the credentials needed to be
314         # refreshed, then refresh the credentials and re-attempt the
315         # request.
316         # A stored token may expire between the time it is retrieved and
317         # the time the request is made, so we may need to try twice.
318         if (
319             response.status_code in self._refresh_status_codes
320             and _credential_refresh_attempt < self._max_refresh_attempts
321         ):
322 
323             _LOGGER.info(
324                 "Refreshing credentials due to a %s response. Attempt %s/%s.",
325                 response.status_code,
326                 _credential_refresh_attempt + 1,
327                 self._max_refresh_attempts,
328             )
329 
330             # Do not apply the timeout unconditionally in order to not override the
331             # _auth_request's default timeout.
332             auth_request = (
333                 self._auth_request
334                 if timeout is None
335                 else functools.partial(self._auth_request, timeout=timeout)
336             )
337 
338             with TimeoutGuard(remaining_time) as guard:
339                 self.credentials.refresh(auth_request)
340             remaining_time = guard.remaining_timeout
341 
342             # Recurse. Pass in the original headers, not our modified set, but
343             # do pass the adjusted max allowed time (i.e. the remaining total time).
344             return self.request(
345                 method,
346                 url,
347                 data=data,
348                 headers=headers,
349                 max_allowed_time=remaining_time,
350                 timeout=timeout,
351                 _credential_refresh_attempt=_credential_refresh_attempt + 1,
352                 **kwargs
353             )
354 
355         return response
356
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/google/auth/transport/requests.py b/google/auth/transport/requests.py
--- a/google/auth/transport/requests.py
+++ b/google/auth/transport/requests.py
@@ -42,6 +42,8 @@
 
 _LOGGER = logging.getLogger(__name__)
 
+_DEFAULT_TIMEOUT = 120  # in seconds
+
 
 class _Response(transport.Response):
     """Requests transport response adapter.
@@ -141,7 +143,13 @@
         self.session = session
 
     def __call__(
-        self, url, method="GET", body=None, headers=None, timeout=120, **kwargs
+        self,
+        url,
+        method="GET",
+        body=None,
+        headers=None,
+        timeout=_DEFAULT_TIMEOUT,
+        **kwargs
     ):
         """Make an HTTP request using requests.
 
@@ -246,7 +254,7 @@
         data=None,
         headers=None,
         max_allowed_time=None,
-        timeout=None,
+        timeout=_DEFAULT_TIMEOUT,
         **kwargs
     ):
         """Implementation of Requests' request.

{"golden_diff": "diff --git a/google/auth/transport/requests.py b/google/auth/transport/requests.py\n--- a/google/auth/transport/requests.py\n+++ b/google/auth/transport/requests.py\n@@ -42,6 +42,8 @@\n \n _LOGGER = logging.getLogger(__name__)\n \n+_DEFAULT_TIMEOUT = 120  # in seconds\n+\n \n class _Response(transport.Response):\n     \"\"\"Requests transport response adapter.\n@@ -141,7 +143,13 @@\n         self.session = session\n \n     def __call__(\n-        self, url, method=\"GET\", body=None, headers=None, timeout=120, **kwargs\n+        self,\n+        url,\n+        method=\"GET\",\n+        body=None,\n+        headers=None,\n+        timeout=_DEFAULT_TIMEOUT,\n+        **kwargs\n     ):\n         \"\"\"Make an HTTP request using requests.\n \n@@ -246,7 +254,7 @@\n         data=None,\n         headers=None,\n         max_allowed_time=None,\n-        timeout=None,\n+        timeout=_DEFAULT_TIMEOUT,\n         **kwargs\n     ):\n         \"\"\"Implementation of Requests' request.\n", "issue": "Set the default request timeout to something other than `None`\nThe [AuthorizedSession.requests()](https://github.com/googleapis/google-auth-library-python/blob/1b9de8dfbe4523f3170e47985ab523cb7865de48/google/auth/transport/requests.py#L242-L251) method does not specify a default timeout.\r\n\r\nSince production code would almost always want to have some sort of a timeout, let's add one. The libraries that rely on `google-auth`, but do (yet) not specify a timeout themselves, would benefit from that.\r\n\r\nExample: [storage issue](https://github.com/googleapis/google-cloud-python/issues/10182)\r\n\n", "before_files": [{"content": "# Copyright 2016 Google Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Transport adapter for Requests.\"\"\"\n\nfrom __future__ import absolute_import\n\nimport functools\nimport logging\nimport numbers\nimport time\n\ntry:\n    import requests\nexcept ImportError as caught_exc:  # pragma: NO COVER\n    import six\n\n    six.raise_from(\n        ImportError(\n            \"The requests library is not installed, please install the \"\n            \"requests package to use the requests transport.\"\n        ),\n        caught_exc,\n    )\nimport requests.adapters  # pylint: disable=ungrouped-imports\nimport requests.exceptions  # pylint: disable=ungrouped-imports\nimport six  # pylint: disable=ungrouped-imports\n\nfrom google.auth import exceptions\nfrom google.auth import transport\n\n_LOGGER = logging.getLogger(__name__)\n\n\nclass _Response(transport.Response):\n    \"\"\"Requests transport response adapter.\n\n    Args:\n        response (requests.Response): The raw Requests response.\n    \"\"\"\n\n    def __init__(self, response):\n        self._response = response\n\n    @property\n    def status(self):\n        return self._response.status_code\n\n    @property\n    def headers(self):\n        return self._response.headers\n\n    @property\n    def data(self):\n        return self._response.content\n\n\nclass TimeoutGuard(object):\n    \"\"\"A context manager raising an error if the suite execution took too long.\n\n    Args:\n        timeout ([Union[None, float, Tuple[float, float]]]):\n            The maximum number of seconds a suite can run without the context\n            manager raising a timeout exception on exit. If passed as a tuple,\n            the smaller of the values is taken as a timeout. If ``None``, a\n            timeout error is never raised.\n        timeout_error_type (Optional[Exception]):\n            The type of the error to raise on timeout. Defaults to\n            :class:`requests.exceptions.Timeout`.\n    \"\"\"\n\n    def __init__(self, timeout, timeout_error_type=requests.exceptions.Timeout):\n        self._timeout = timeout\n        self.remaining_timeout = timeout\n        self._timeout_error_type = timeout_error_type\n\n    def __enter__(self):\n        self._start = time.time()\n        return self\n\n    def __exit__(self, exc_type, exc_value, traceback):\n        if exc_value:\n            return  # let the error bubble up automatically\n\n        if self._timeout is None:\n            return  # nothing to do, the timeout was not specified\n\n        elapsed = time.time() - self._start\n        deadline_hit = False\n\n        if isinstance(self._timeout, numbers.Number):\n            self.remaining_timeout = self._timeout - elapsed\n            deadline_hit = self.remaining_timeout <= 0\n        else:\n            self.remaining_timeout = tuple(x - elapsed for x in self._timeout)\n            deadline_hit = min(self.remaining_timeout) <= 0\n\n        if deadline_hit:\n            raise self._timeout_error_type()\n\n\nclass Request(transport.Request):\n    \"\"\"Requests request adapter.\n\n    This class is used internally for making requests using various transports\n    in a consistent way. If you use :class:`AuthorizedSession` you do not need\n    to construct or use this class directly.\n\n    This class can be useful if you want to manually refresh a\n    :class:`~google.auth.credentials.Credentials` instance::\n\n        import google.auth.transport.requests\n        import requests\n\n        request = google.auth.transport.requests.Request()\n\n        credentials.refresh(request)\n\n    Args:\n        session (requests.Session): An instance :class:`requests.Session` used\n            to make HTTP requests. If not specified, a session will be created.\n\n    .. automethod:: __call__\n    \"\"\"\n\n    def __init__(self, session=None):\n        if not session:\n            session = requests.Session()\n\n        self.session = session\n\n    def __call__(\n        self, url, method=\"GET\", body=None, headers=None, timeout=120, **kwargs\n    ):\n        \"\"\"Make an HTTP request using requests.\n\n        Args:\n            url (str): The URI to be requested.\n            method (str): The HTTP method to use for the request. Defaults\n                to 'GET'.\n            body (bytes): The payload / body in HTTP request.\n            headers (Mapping[str, str]): Request headers.\n            timeout (Optional[int]): The number of seconds to wait for a\n                response from the server. If not specified or if None, the\n                requests default timeout will be used.\n            kwargs: Additional arguments passed through to the underlying\n                requests :meth:`~requests.Session.request` method.\n\n        Returns:\n            google.auth.transport.Response: The HTTP response.\n\n        Raises:\n            google.auth.exceptions.TransportError: If any exception occurred.\n        \"\"\"\n        try:\n            _LOGGER.debug(\"Making request: %s %s\", method, url)\n            response = self.session.request(\n                method, url, data=body, headers=headers, timeout=timeout, **kwargs\n            )\n            return _Response(response)\n        except requests.exceptions.RequestException as caught_exc:\n            new_exc = exceptions.TransportError(caught_exc)\n            six.raise_from(new_exc, caught_exc)\n\n\nclass AuthorizedSession(requests.Session):\n    \"\"\"A Requests Session class with credentials.\n\n    This class is used to perform requests to API endpoints that require\n    authorization::\n\n        from google.auth.transport.requests import AuthorizedSession\n\n        authed_session = AuthorizedSession(credentials)\n\n        response = authed_session.request(\n            'GET', 'https://www.googleapis.com/storage/v1/b')\n\n    The underlying :meth:`request` implementation handles adding the\n    credentials' headers to the request and refreshing credentials as needed.\n\n    Args:\n        credentials (google.auth.credentials.Credentials): The credentials to\n            add to the request.\n        refresh_status_codes (Sequence[int]): Which HTTP status codes indicate\n            that credentials should be refreshed and the request should be\n            retried.\n        max_refresh_attempts (int): The maximum number of times to attempt to\n            refresh the credentials and retry the request.\n        refresh_timeout (Optional[int]): The timeout value in seconds for\n            credential refresh HTTP requests.\n        auth_request (google.auth.transport.requests.Request):\n            (Optional) An instance of\n            :class:`~google.auth.transport.requests.Request` used when\n            refreshing credentials. If not passed,\n            an instance of :class:`~google.auth.transport.requests.Request`\n            is created.\n    \"\"\"\n\n    def __init__(\n        self,\n        credentials,\n        refresh_status_codes=transport.DEFAULT_REFRESH_STATUS_CODES,\n        max_refresh_attempts=transport.DEFAULT_MAX_REFRESH_ATTEMPTS,\n        refresh_timeout=None,\n        auth_request=None,\n    ):\n        super(AuthorizedSession, self).__init__()\n        self.credentials = credentials\n        self._refresh_status_codes = refresh_status_codes\n        self._max_refresh_attempts = max_refresh_attempts\n        self._refresh_timeout = refresh_timeout\n\n        if auth_request is None:\n            auth_request_session = requests.Session()\n\n            # Using an adapter to make HTTP requests robust to network errors.\n            # This adapter retrys HTTP requests when network errors occur\n            # and the requests seems safely retryable.\n            retry_adapter = requests.adapters.HTTPAdapter(max_retries=3)\n            auth_request_session.mount(\"https://\", retry_adapter)\n\n            # Do not pass `self` as the session here, as it can lead to\n            # infinite recursion.\n            auth_request = Request(auth_request_session)\n\n        # Request instance used by internal methods (for example,\n        # credentials.refresh).\n        self._auth_request = auth_request\n\n    def request(\n        self,\n        method,\n        url,\n        data=None,\n        headers=None,\n        max_allowed_time=None,\n        timeout=None,\n        **kwargs\n    ):\n        \"\"\"Implementation of Requests' request.\n\n        Args:\n            timeout (Optional[Union[float, Tuple[float, float]]]):\n                The amount of time in seconds to wait for the server response\n                with each individual request.\n\n                Can also be passed as a tuple (connect_timeout, read_timeout).\n                See :meth:`requests.Session.request` documentation for details.\n\n            max_allowed_time (Optional[float]):\n                If the method runs longer than this, a ``Timeout`` exception is\n                automatically raised. Unlike the ``timeout` parameter, this\n                value applies to the total method execution time, even if\n                multiple requests are made under the hood.\n\n                Mind that it is not guaranteed that the timeout error is raised\n                at ``max_allowed_time`. It might take longer, for example, if\n                an underlying request takes a lot of time, but the request\n                itself does not timeout, e.g. if a large file is being\n                transmitted. The timout error will be raised after such\n                request completes.\n        \"\"\"\n        # pylint: disable=arguments-differ\n        # Requests has a ton of arguments to request, but only two\n        # (method, url) are required. We pass through all of the other\n        # arguments to super, so no need to exhaustively list them here.\n\n        # Use a kwarg for this instead of an attribute to maintain\n        # thread-safety.\n        _credential_refresh_attempt = kwargs.pop(\"_credential_refresh_attempt\", 0)\n\n        # Make a copy of the headers. They will be modified by the credentials\n        # and we want to pass the original headers if we recurse.\n        request_headers = headers.copy() if headers is not None else {}\n\n        # Do not apply the timeout unconditionally in order to not override the\n        # _auth_request's default timeout.\n        auth_request = (\n            self._auth_request\n            if timeout is None\n            else functools.partial(self._auth_request, timeout=timeout)\n        )\n\n        remaining_time = max_allowed_time\n\n        with TimeoutGuard(remaining_time) as guard:\n            self.credentials.before_request(auth_request, method, url, request_headers)\n        remaining_time = guard.remaining_timeout\n\n        with TimeoutGuard(remaining_time) as guard:\n            response = super(AuthorizedSession, self).request(\n                method,\n                url,\n                data=data,\n                headers=request_headers,\n                timeout=timeout,\n                **kwargs\n            )\n        remaining_time = guard.remaining_timeout\n\n        # If the response indicated that the credentials needed to be\n        # refreshed, then refresh the credentials and re-attempt the\n        # request.\n        # A stored token may expire between the time it is retrieved and\n        # the time the request is made, so we may need to try twice.\n        if (\n            response.status_code in self._refresh_status_codes\n            and _credential_refresh_attempt < self._max_refresh_attempts\n        ):\n\n            _LOGGER.info(\n                \"Refreshing credentials due to a %s response. Attempt %s/%s.\",\n                response.status_code,\n                _credential_refresh_attempt + 1,\n                self._max_refresh_attempts,\n            )\n\n            # Do not apply the timeout unconditionally in order to not override the\n            # _auth_request's default timeout.\n            auth_request = (\n                self._auth_request\n                if timeout is None\n                else functools.partial(self._auth_request, timeout=timeout)\n            )\n\n            with TimeoutGuard(remaining_time) as guard:\n                self.credentials.refresh(auth_request)\n            remaining_time = guard.remaining_timeout\n\n            # Recurse. Pass in the original headers, not our modified set, but\n            # do pass the adjusted max allowed time (i.e. the remaining total time).\n            return self.request(\n                method,\n                url,\n                data=data,\n                headers=headers,\n                max_allowed_time=remaining_time,\n                timeout=timeout,\n                _credential_refresh_attempt=_credential_refresh_attempt + 1,\n                **kwargs\n            )\n\n        return response\n", "path": "google/auth/transport/requests.py"}], "after_files": [{"content": "# Copyright 2016 Google Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Transport adapter for Requests.\"\"\"\n\nfrom __future__ import absolute_import\n\nimport functools\nimport logging\nimport numbers\nimport time\n\ntry:\n    import requests\nexcept ImportError as caught_exc:  # pragma: NO COVER\n    import six\n\n    six.raise_from(\n        ImportError(\n            \"The requests library is not installed, please install the \"\n            \"requests package to use the requests transport.\"\n        ),\n        caught_exc,\n    )\nimport requests.adapters  # pylint: disable=ungrouped-imports\nimport requests.exceptions  # pylint: disable=ungrouped-imports\nimport six  # pylint: disable=ungrouped-imports\n\nfrom google.auth import exceptions\nfrom google.auth import transport\n\n_LOGGER = logging.getLogger(__name__)\n\n_DEFAULT_TIMEOUT = 120  # in seconds\n\n\nclass _Response(transport.Response):\n    \"\"\"Requests transport response adapter.\n\n    Args:\n        response (requests.Response): The raw Requests response.\n    \"\"\"\n\n    def __init__(self, response):\n        self._response = response\n\n    @property\n    def status(self):\n        return self._response.status_code\n\n    @property\n    def headers(self):\n        return self._response.headers\n\n    @property\n    def data(self):\n        return self._response.content\n\n\nclass TimeoutGuard(object):\n    \"\"\"A context manager raising an error if the suite execution took too long.\n\n    Args:\n        timeout ([Union[None, float, Tuple[float, float]]]):\n            The maximum number of seconds a suite can run without the context\n            manager raising a timeout exception on exit. If passed as a tuple,\n            the smaller of the values is taken as a timeout. If ``None``, a\n            timeout error is never raised.\n        timeout_error_type (Optional[Exception]):\n            The type of the error to raise on timeout. Defaults to\n            :class:`requests.exceptions.Timeout`.\n    \"\"\"\n\n    def __init__(self, timeout, timeout_error_type=requests.exceptions.Timeout):\n        self._timeout = timeout\n        self.remaining_timeout = timeout\n        self._timeout_error_type = timeout_error_type\n\n    def __enter__(self):\n        self._start = time.time()\n        return self\n\n    def __exit__(self, exc_type, exc_value, traceback):\n        if exc_value:\n            return  # let the error bubble up automatically\n\n        if self._timeout is None:\n            return  # nothing to do, the timeout was not specified\n\n        elapsed = time.time() - self._start\n        deadline_hit = False\n\n        if isinstance(self._timeout, numbers.Number):\n            self.remaining_timeout = self._timeout - elapsed\n            deadline_hit = self.remaining_timeout <= 0\n        else:\n            self.remaining_timeout = tuple(x - elapsed for x in self._timeout)\n            deadline_hit = min(self.remaining_timeout) <= 0\n\n        if deadline_hit:\n            raise self._timeout_error_type()\n\n\nclass Request(transport.Request):\n    \"\"\"Requests request adapter.\n\n    This class is used internally for making requests using various transports\n    in a consistent way. If you use :class:`AuthorizedSession` you do not need\n    to construct or use this class directly.\n\n    This class can be useful if you want to manually refresh a\n    :class:`~google.auth.credentials.Credentials` instance::\n\n        import google.auth.transport.requests\n        import requests\n\n        request = google.auth.transport.requests.Request()\n\n        credentials.refresh(request)\n\n    Args:\n        session (requests.Session): An instance :class:`requests.Session` used\n            to make HTTP requests. If not specified, a session will be created.\n\n    .. automethod:: __call__\n    \"\"\"\n\n    def __init__(self, session=None):\n        if not session:\n            session = requests.Session()\n\n        self.session = session\n\n    def __call__(\n        self,\n        url,\n        method=\"GET\",\n        body=None,\n        headers=None,\n        timeout=_DEFAULT_TIMEOUT,\n        **kwargs\n    ):\n        \"\"\"Make an HTTP request using requests.\n\n        Args:\n            url (str): The URI to be requested.\n            method (str): The HTTP method to use for the request. Defaults\n                to 'GET'.\n            body (bytes): The payload / body in HTTP request.\n            headers (Mapping[str, str]): Request headers.\n            timeout (Optional[int]): The number of seconds to wait for a\n                response from the server. If not specified or if None, the\n                requests default timeout will be used.\n            kwargs: Additional arguments passed through to the underlying\n                requests :meth:`~requests.Session.request` method.\n\n        Returns:\n            google.auth.transport.Response: The HTTP response.\n\n        Raises:\n            google.auth.exceptions.TransportError: If any exception occurred.\n        \"\"\"\n        try:\n            _LOGGER.debug(\"Making request: %s %s\", method, url)\n            response = self.session.request(\n                method, url, data=body, headers=headers, timeout=timeout, **kwargs\n            )\n            return _Response(response)\n        except requests.exceptions.RequestException as caught_exc:\n            new_exc = exceptions.TransportError(caught_exc)\n            six.raise_from(new_exc, caught_exc)\n\n\nclass AuthorizedSession(requests.Session):\n    \"\"\"A Requests Session class with credentials.\n\n    This class is used to perform requests to API endpoints that require\n    authorization::\n\n        from google.auth.transport.requests import AuthorizedSession\n\n        authed_session = AuthorizedSession(credentials)\n\n        response = authed_session.request(\n            'GET', 'https://www.googleapis.com/storage/v1/b')\n\n    The underlying :meth:`request` implementation handles adding the\n    credentials' headers to the request and refreshing credentials as needed.\n\n    Args:\n        credentials (google.auth.credentials.Credentials): The credentials to\n            add to the request.\n        refresh_status_codes (Sequence[int]): Which HTTP status codes indicate\n            that credentials should be refreshed and the request should be\n            retried.\n        max_refresh_attempts (int): The maximum number of times to attempt to\n            refresh the credentials and retry the request.\n        refresh_timeout (Optional[int]): The timeout value in seconds for\n            credential refresh HTTP requests.\n        auth_request (google.auth.transport.requests.Request):\n            (Optional) An instance of\n            :class:`~google.auth.transport.requests.Request` used when\n            refreshing credentials. If not passed,\n            an instance of :class:`~google.auth.transport.requests.Request`\n            is created.\n    \"\"\"\n\n    def __init__(\n        self,\n        credentials,\n        refresh_status_codes=transport.DEFAULT_REFRESH_STATUS_CODES,\n        max_refresh_attempts=transport.DEFAULT_MAX_REFRESH_ATTEMPTS,\n        refresh_timeout=None,\n        auth_request=None,\n    ):\n        super(AuthorizedSession, self).__init__()\n        self.credentials = credentials\n        self._refresh_status_codes = refresh_status_codes\n        self._max_refresh_attempts = max_refresh_attempts\n        self._refresh_timeout = refresh_timeout\n\n        if auth_request is None:\n            auth_request_session = requests.Session()\n\n            # Using an adapter to make HTTP requests robust to network errors.\n            # This adapter retrys HTTP requests when network errors occur\n            # and the requests seems safely retryable.\n            retry_adapter = requests.adapters.HTTPAdapter(max_retries=3)\n            auth_request_session.mount(\"https://\", retry_adapter)\n\n            # Do not pass `self` as the session here, as it can lead to\n            # infinite recursion.\n            auth_request = Request(auth_request_session)\n\n        # Request instance used by internal methods (for example,\n        # credentials.refresh).\n        self._auth_request = auth_request\n\n    def request(\n        self,\n        method,\n        url,\n        data=None,\n        headers=None,\n        max_allowed_time=None,\n        timeout=_DEFAULT_TIMEOUT,\n        **kwargs\n    ):\n        \"\"\"Implementation of Requests' request.\n\n        Args:\n            timeout (Optional[Union[float, Tuple[float, float]]]):\n                The amount of time in seconds to wait for the server response\n                with each individual request.\n\n                Can also be passed as a tuple (connect_timeout, read_timeout).\n                See :meth:`requests.Session.request` documentation for details.\n\n            max_allowed_time (Optional[float]):\n                If the method runs longer than this, a ``Timeout`` exception is\n                automatically raised. Unlike the ``timeout` parameter, this\n                value applies to the total method execution time, even if\n                multiple requests are made under the hood.\n\n                Mind that it is not guaranteed that the timeout error is raised\n                at ``max_allowed_time`. It might take longer, for example, if\n                an underlying request takes a lot of time, but the request\n                itself does not timeout, e.g. if a large file is being\n                transmitted. The timout error will be raised after such\n                request completes.\n        \"\"\"\n        # pylint: disable=arguments-differ\n        # Requests has a ton of arguments to request, but only two\n        # (method, url) are required. We pass through all of the other\n        # arguments to super, so no need to exhaustively list them here.\n\n        # Use a kwarg for this instead of an attribute to maintain\n        # thread-safety.\n        _credential_refresh_attempt = kwargs.pop(\"_credential_refresh_attempt\", 0)\n\n        # Make a copy of the headers. They will be modified by the credentials\n        # and we want to pass the original headers if we recurse.\n        request_headers = headers.copy() if headers is not None else {}\n\n        # Do not apply the timeout unconditionally in order to not override the\n        # _auth_request's default timeout.\n        auth_request = (\n            self._auth_request\n            if timeout is None\n            else functools.partial(self._auth_request, timeout=timeout)\n        )\n\n        remaining_time = max_allowed_time\n\n        with TimeoutGuard(remaining_time) as guard:\n            self.credentials.before_request(auth_request, method, url, request_headers)\n        remaining_time = guard.remaining_timeout\n\n        with TimeoutGuard(remaining_time) as guard:\n            response = super(AuthorizedSession, self).request(\n                method,\n                url,\n                data=data,\n                headers=request_headers,\n                timeout=timeout,\n                **kwargs\n            )\n        remaining_time = guard.remaining_timeout\n\n        # If the response indicated that the credentials needed to be\n        # refreshed, then refresh the credentials and re-attempt the\n        # request.\n        # A stored token may expire between the time it is retrieved and\n        # the time the request is made, so we may need to try twice.\n        if (\n            response.status_code in self._refresh_status_codes\n            and _credential_refresh_attempt < self._max_refresh_attempts\n        ):\n\n            _LOGGER.info(\n                \"Refreshing credentials due to a %s response. Attempt %s/%s.\",\n                response.status_code,\n                _credential_refresh_attempt + 1,\n                self._max_refresh_attempts,\n            )\n\n            # Do not apply the timeout unconditionally in order to not override the\n            # _auth_request's default timeout.\n            auth_request = (\n                self._auth_request\n                if timeout is None\n                else functools.partial(self._auth_request, timeout=timeout)\n            )\n\n            with TimeoutGuard(remaining_time) as guard:\n                self.credentials.refresh(auth_request)\n            remaining_time = guard.remaining_timeout\n\n            # Recurse. Pass in the original headers, not our modified set, but\n            # do pass the adjusted max allowed time (i.e. the remaining total time).\n            return self.request(\n                method,\n                url,\n                data=data,\n                headers=headers,\n                max_allowed_time=remaining_time,\n                timeout=timeout,\n                _credential_refresh_attempt=_credential_refresh_attempt + 1,\n                **kwargs\n            )\n\n        return response\n", "path": "google/auth/transport/requests.py"}]}