Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
google_auth_httplib2.py308 linesDownload Raw Back to site-packages
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 at6#7#      http://www.apache.org/licenses/LICENSE-2.08#9# Unless required by applicable law or agreed to in writing, software10# 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 and13# limitations under the License.14 15"""Transport adapter for httplib2."""16 17from __future__ import absolute_import18 19import http.client20import logging21 22from google.auth import exceptions23from google.auth import transport24import httplib225 26 27_LOGGER = logging.getLogger(__name__)28# Properties present in file-like streams / buffers.29_STREAM_PROPERTIES = ("read", "seek", "tell")30 31 32class _Response(transport.Response):33    """httplib2 transport response adapter.34 35    Args:36        response (httplib2.Response): The raw httplib2 response.37        data (bytes): The response body.38    """39 40    def __init__(self, response, data):41        self._response = response42        self._data = data43 44    @property45    def status(self):46        """int: The HTTP status code."""47        return self._response.status48 49    @property50    def headers(self):51        """Mapping[str, str]: The HTTP response headers."""52        return dict(self._response)53 54    @property55    def data(self):56        """bytes: The response body."""57        return self._data58 59 60class Request(transport.Request):61    """httplib2 request adapter.62 63    This class is used internally for making requests using various transports64    in a consistent way. If you use :class:`AuthorizedHttp` you do not need65    to construct or use this class directly.66 67    This class can be useful if you want to manually refresh a68    :class:`~google.auth.credentials.Credentials` instance::69 70        import google_auth_httplib271        import httplib272 73        http = httplib2.Http()74        request = google_auth_httplib2.Request(http)75 76        credentials.refresh(request)77 78    Args:79        http (httplib2.Http): The underlying http object to use to make80            requests.81 82    .. automethod:: __call__83    """84 85    def __init__(self, http):86        self.http = http87 88    def __call__(89        self, url, method="GET", body=None, headers=None, timeout=None, **kwargs90    ):91        """Make an HTTP request using httplib2.92 93        Args:94            url (str): The URI to be requested.95            method (str): The HTTP method to use for the request. Defaults96                to 'GET'.97            body (bytes): The payload / body in HTTP request.98            headers (Mapping[str, str]): Request headers.99            timeout (Optional[int]): The number of seconds to wait for a100                response from the server. This is ignored by httplib2 and will101                issue a warning.102            kwargs: Additional arguments passed throught to the underlying103                :meth:`httplib2.Http.request` method.104 105        Returns:106            google.auth.transport.Response: The HTTP response.107 108        Raises:109            google.auth.exceptions.TransportError: If any exception occurred.110        """111        if timeout is not None:112            _LOGGER.warning(113                "httplib2 transport does not support per-request timeout. "114                "Set the timeout when constructing the httplib2.Http instance."115            )116 117        try:118            _LOGGER.debug("Making request: %s %s", method, url)119            response, data = self.http.request(120                url, method=method, body=body, headers=headers, **kwargs121            )122            return _Response(response, data)123        # httplib2 should catch the lower http error, this is a bug and124        # needs to be fixed there.  Catch the error for the meanwhile.125        except (httplib2.HttpLib2Error, http.client.HTTPException) as exc:126            raise exceptions.TransportError(exc)127 128 129def _make_default_http():130    """Returns a default httplib2.Http instance."""131    return httplib2.Http()132 133 134class AuthorizedHttp(object):135    """A httplib2 HTTP class with credentials.136 137    This class is used to perform requests to API endpoints that require138    authorization::139 140        from google.auth.transport._httplib2 import AuthorizedHttp141 142        authed_http = AuthorizedHttp(credentials)143 144        response = authed_http.request(145            'https://www.googleapis.com/storage/v1/b')146 147    This class implements :meth:`request` in the same way as148    :class:`httplib2.Http` and can usually be used just like any other149    instance of :class:``httplib2.Http`.150 151    The underlying :meth:`request` implementation handles adding the152    credentials' headers to the request and refreshing credentials as needed.153    """154 155    def __init__(156        self,157        credentials,158        http=None,159        refresh_status_codes=transport.DEFAULT_REFRESH_STATUS_CODES,160        max_refresh_attempts=transport.DEFAULT_MAX_REFRESH_ATTEMPTS,161    ):162        """163        Args:164            credentials (google.auth.credentials.Credentials): The credentials165                to add to the request.166            http (httplib2.Http): The underlying HTTP object to167                use to make requests. If not specified, a168                :class:`httplib2.Http` instance will be constructed.169            refresh_status_codes (Sequence[int]): Which HTTP status codes170                indicate that credentials should be refreshed and the request171                should be retried.172            max_refresh_attempts (int): The maximum number of times to attempt173                to refresh the credentials and retry the request.174        """175 176        if http is None:177            http = _make_default_http()178 179        self.http = http180        self.credentials = credentials181        self._refresh_status_codes = refresh_status_codes182        self._max_refresh_attempts = max_refresh_attempts183        # Request instance used by internal methods (for example,184        # credentials.refresh).185        self._request = Request(self.http)186 187    def close(self):188        """Calls httplib2's Http.close"""189        self.http.close()190 191    def request(192        self,193        uri,194        method="GET",195        body=None,196        headers=None,197        redirections=httplib2.DEFAULT_MAX_REDIRECTS,198        connection_type=None,199        **kwargs200    ):201        """Implementation of httplib2's Http.request."""202 203        _credential_refresh_attempt = kwargs.pop("_credential_refresh_attempt", 0)204 205        # Make a copy of the headers. They will be modified by the credentials206        # and we want to pass the original headers if we recurse.207        request_headers = headers.copy() if headers is not None else {}208 209        self.credentials.before_request(self._request, method, uri, request_headers)210 211        # Check if the body is a file-like stream, and if so, save the body212        # stream position so that it can be restored in case of refresh.213        body_stream_position = None214        if all(getattr(body, stream_prop, None) for stream_prop in _STREAM_PROPERTIES):215            body_stream_position = body.tell()216 217        # Make the request.218        response, content = self.http.request(219            uri,220            method,221            body=body,222            headers=request_headers,223            redirections=redirections,224            connection_type=connection_type,225            **kwargs226        )227 228        # If the response indicated that the credentials needed to be229        # refreshed, then refresh the credentials and re-attempt the230        # request.231        # A stored token may expire between the time it is retrieved and232        # the time the request is made, so we may need to try twice.233        if (234            response.status in self._refresh_status_codes235            and _credential_refresh_attempt < self._max_refresh_attempts236        ):237 238            _LOGGER.info(239                "Refreshing credentials due to a %s response. Attempt %s/%s.",240                response.status,241                _credential_refresh_attempt + 1,242                self._max_refresh_attempts,243            )244 245            self.credentials.refresh(self._request)246 247            # Restore the body's stream position if needed.248            if body_stream_position is not None:249                body.seek(body_stream_position)250 251            # Recurse. Pass in the original headers, not our modified set.252            return self.request(253                uri,254                method,255                body=body,256                headers=headers,257                redirections=redirections,258                connection_type=connection_type,259                _credential_refresh_attempt=_credential_refresh_attempt + 1,260                **kwargs261            )262 263        return response, content264 265    def add_certificate(self, key, cert, domain, password=None):266        """Proxy to httplib2.Http.add_certificate."""267        self.http.add_certificate(key, cert, domain, password=password)268 269    @property270    def connections(self):271        """Proxy to httplib2.Http.connections."""272        return self.http.connections273 274    @connections.setter275    def connections(self, value):276        """Proxy to httplib2.Http.connections."""277        self.http.connections = value278 279    @property280    def follow_redirects(self):281        """Proxy to httplib2.Http.follow_redirects."""282        return self.http.follow_redirects283 284    @follow_redirects.setter285    def follow_redirects(self, value):286        """Proxy to httplib2.Http.follow_redirects."""287        self.http.follow_redirects = value288 289    @property290    def timeout(self):291        """Proxy to httplib2.Http.timeout."""292        return self.http.timeout293 294    @timeout.setter295    def timeout(self, value):296        """Proxy to httplib2.Http.timeout."""297        self.http.timeout = value298 299    @property300    def redirect_codes(self):301        """Proxy to httplib2.Http.redirect_codes."""302        return self.http.redirect_codes303 304    @redirect_codes.setter305    def redirect_codes(self, value):306        """Proxy to httplib2.Http.redirect_codes."""307        self.http.redirect_codes = value308 
codekingpro/portable-devtools · Team Ai