Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(238)

Side by Side Diff: client/third_party/google/auth/transport/requests.py

Issue 2953253003: Replace custom blob gRPC API with ByteStream (Closed)
Patch Set: Import ndb directly to test code Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 logging
20
21 try:
22 import requests
23 except ImportError: # pragma: NO COVER
24 raise ImportError(
25 'The requests library is not installed, please install the requests '
26 'package to use the requests transport.')
27 import requests.exceptions
28
29 from google.auth import exceptions
30 from google.auth import transport
31
32 _LOGGER = logging.getLogger(__name__)
33
34
35 class _Response(transport.Response):
36 """Requests transport response adapter.
37
38 Args:
39 response (requests.Response): The raw Requests response.
40 """
41 def __init__(self, response):
42 self._response = response
43
44 @property
45 def status(self):
46 return self._response.status_code
47
48 @property
49 def headers(self):
50 return self._response.headers
51
52 @property
53 def data(self):
54 return self._response.content
55
56
57 class Request(transport.Request):
58 """Requests request adapter.
59
60 This class is used internally for making requests using various transports
61 in a consistent way. If you use :class:`AuthorizedSession` you do not need
62 to construct or use this class directly.
63
64 This class can be useful if you want to manually refresh a
65 :class:`~google.auth.credentials.Credentials` instance::
66
67 import google.auth.transport.requests
68 import requests
69
70 request = google.auth.transport.requests.Request()
71
72 credentials.refresh(request)
73
74 Args:
75 session (requests.Session): An instance :class:`requests.Session` used
76 to make HTTP requests. If not specified, a session will be created.
77
78 .. automethod:: __call__
79 """
80 def __init__(self, session=None):
81 if not session:
82 session = requests.Session()
83
84 self.session = session
85
86 def __call__(self, url, method='GET', body=None, headers=None,
87 timeout=None, **kwargs):
88 """Make an HTTP request using requests.
89
90 Args:
91 url (str): The URI to be requested.
92 method (str): The HTTP method to use for the request. Defaults
93 to 'GET'.
94 body (bytes): The payload / body in HTTP request.
95 headers (Mapping[str, str]): Request headers.
96 timeout (Optional[int]): The number of seconds to wait for a
97 response from the server. If not specified or if None, the
98 requests default timeout will be used.
99 kwargs: Additional arguments passed through to the underlying
100 requests :meth:`~requests.Session.request` method.
101
102 Returns:
103 google.auth.transport.Response: The HTTP response.
104
105 Raises:
106 google.auth.exceptions.TransportError: If any exception occurred.
107 """
108 try:
109 _LOGGER.debug('Making request: %s %s', method, url)
110 response = self.session.request(
111 method, url, data=body, headers=headers, timeout=timeout,
112 **kwargs)
113 return _Response(response)
114 except requests.exceptions.RequestException as exc:
115 raise exceptions.TransportError(exc)
116
117
118 class AuthorizedSession(requests.Session):
119 """A Requests Session class with credentials.
120
121 This class is used to perform requests to API endpoints that require
122 authorization::
123
124 from google.auth.transport.requests import AuthorizedSession
125
126 authed_session = AuthorizedSession(credentials)
127
128 response = authed_session.request(
129 'GET', 'https://www.googleapis.com/storage/v1/b')
130
131 The underlying :meth:`request` implementation handles adding the
132 credentials' headers to the request and refreshing credentials as needed.
133
134 Args:
135 credentials (google.auth.credentials.Credentials): The credentials to
136 add to the request.
137 refresh_status_codes (Sequence[int]): Which HTTP status codes indicate
138 that credentials should be refreshed and the request should be
139 retried.
140 max_refresh_attempts (int): The maximum number of times to attempt to
141 refresh the credentials and retry the request.
142 kwargs: Additional arguments passed to the :class:`requests.Session`
143 constructor.
144 """
145 def __init__(self, credentials,
146 refresh_status_codes=transport.DEFAULT_REFRESH_STATUS_CODES,
147 max_refresh_attempts=transport.DEFAULT_MAX_REFRESH_ATTEMPTS,
148 **kwargs):
149 super(AuthorizedSession, self).__init__(**kwargs)
150 self.credentials = credentials
151 self._refresh_status_codes = refresh_status_codes
152 self._max_refresh_attempts = max_refresh_attempts
153 # Request instance used by internal methods (for example,
154 # credentials.refresh).
155 # Do not pass `self` as the session here, as it can lead to infinite
156 # recursion.
157 self._auth_request = Request()
158
159 def request(self, method, url, data=None, headers=None, **kwargs):
160 """Implementation of Requests' request."""
161 # pylint: disable=arguments-differ
162 # Requests has a ton of arguments to request, but only two
163 # (method, url) are required. We pass through all of the other
164 # arguments to super, so no need to exhaustively list them here.
165
166 # Use a kwarg for this instead of an attribute to maintain
167 # thread-safety.
168 _credential_refresh_attempt = kwargs.pop(
169 '_credential_refresh_attempt', 0)
170
171 # Make a copy of the headers. They will be modified by the credentials
172 # and we want to pass the original headers if we recurse.
173 request_headers = headers.copy() if headers is not None else {}
174
175 self.credentials.before_request(
176 self._auth_request, method, url, request_headers)
177
178 response = super(AuthorizedSession, self).request(
179 method, url, data=data, headers=request_headers, **kwargs)
180
181 # If the response indicated that the credentials needed to be
182 # refreshed, then refresh the credentials and re-attempt the
183 # request.
184 # A stored token may expire between the time it is retrieved and
185 # the time the request is made, so we may need to try twice.
186 if (response.status_code in self._refresh_status_codes
187 and _credential_refresh_attempt < self._max_refresh_attempts):
188
189 _LOGGER.info(
190 'Refreshing credentials due to a %s response. Attempt %s/%s.',
191 response.status_code, _credential_refresh_attempt + 1,
192 self._max_refresh_attempts)
193
194 self.credentials.refresh(self._auth_request)
195
196 # Recurse. Pass in the original headers, not our modified set.
197 return self.request(
198 method, url, data=data, headers=headers,
199 _credential_refresh_attempt=_credential_refresh_attempt + 1,
200 **kwargs)
201
202 return response
OLDNEW
« no previous file with comments | « client/third_party/google/auth/transport/grpc.py ('k') | client/third_party/google/auth/transport/urllib3.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698