mirror of
https://github.com/GAM-team/GAM.git
synced 2025-07-09 06:03:35 +00:00
googleapiclient 1.6.3
This commit is contained in:
@ -12,7 +12,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
__version__ = "1.6.2"
|
__version__ = "1.6.3"
|
||||||
|
|
||||||
# Set default logging handler to avoid "No handler found" warnings.
|
# Set default logging handler to avoid "No handler found" warnings.
|
||||||
import logging
|
import logging
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
"""Helpers for authentication using oauth2client or google-auth."""
|
"""Helpers for authentication using oauth2client or google-auth."""
|
||||||
|
|
||||||
|
import httplib2
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import google.auth
|
import google.auth
|
||||||
import google.auth.credentials
|
import google.auth.credentials
|
||||||
@ -29,8 +31,6 @@ try:
|
|||||||
except ImportError: # pragma: NO COVER
|
except ImportError: # pragma: NO COVER
|
||||||
HAS_OAUTH2CLIENT = False
|
HAS_OAUTH2CLIENT = False
|
||||||
|
|
||||||
from googleapiclient.http import build_http
|
|
||||||
|
|
||||||
|
|
||||||
def default_credentials():
|
def default_credentials():
|
||||||
"""Returns Application Default Credentials."""
|
"""Returns Application Default Credentials."""
|
||||||
@ -84,9 +84,50 @@ def authorized_http(credentials):
|
|||||||
Union[httplib2.Http, google_auth_httplib2.AuthorizedHttp]: An
|
Union[httplib2.Http, google_auth_httplib2.AuthorizedHttp]: An
|
||||||
authorized http client.
|
authorized http client.
|
||||||
"""
|
"""
|
||||||
|
from googleapiclient.http import build_http
|
||||||
|
|
||||||
if HAS_GOOGLE_AUTH and isinstance(
|
if HAS_GOOGLE_AUTH and isinstance(
|
||||||
credentials, google.auth.credentials.Credentials):
|
credentials, google.auth.credentials.Credentials):
|
||||||
return google_auth_httplib2.AuthorizedHttp(credentials,
|
return google_auth_httplib2.AuthorizedHttp(credentials,
|
||||||
http=build_http())
|
http=build_http())
|
||||||
else:
|
else:
|
||||||
return credentials.authorize(build_http())
|
return credentials.authorize(build_http())
|
||||||
|
|
||||||
|
|
||||||
|
def refresh_credentials(credentials):
|
||||||
|
# Refresh must use a new http instance, as the one associated with the
|
||||||
|
# credentials could be a AuthorizedHttp or an oauth2client-decorated
|
||||||
|
# Http instance which would cause a weird recursive loop of refreshing
|
||||||
|
# and likely tear a hole in spacetime.
|
||||||
|
refresh_http = httplib2.Http()
|
||||||
|
if HAS_GOOGLE_AUTH and isinstance(
|
||||||
|
credentials, google.auth.credentials.Credentials):
|
||||||
|
request = google_auth_httplib2.Request(refresh_http)
|
||||||
|
return credentials.refresh(request)
|
||||||
|
else:
|
||||||
|
return credentials.refresh(refresh_http)
|
||||||
|
|
||||||
|
|
||||||
|
def apply_credentials(credentials, headers):
|
||||||
|
# oauth2client and google-auth have the same interface for this.
|
||||||
|
return credentials.apply(headers)
|
||||||
|
|
||||||
|
|
||||||
|
def is_valid(credentials):
|
||||||
|
if HAS_GOOGLE_AUTH and isinstance(
|
||||||
|
credentials, google.auth.credentials.Credentials):
|
||||||
|
return credentials.valid
|
||||||
|
else:
|
||||||
|
return not credentials.access_token_expired
|
||||||
|
|
||||||
|
|
||||||
|
def get_credentials_from_http(http):
|
||||||
|
if http is None:
|
||||||
|
return None
|
||||||
|
elif hasattr(http.request, 'credentials'):
|
||||||
|
return http.request.credentials
|
||||||
|
elif (hasattr(http, 'credentials')
|
||||||
|
and not isinstance(http.credentials, httplib2.Credentials)):
|
||||||
|
return http.credentials
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
@ -46,6 +46,7 @@ class HttpError(Error):
|
|||||||
raise TypeError("HTTP content should be bytes")
|
raise TypeError("HTTP content should be bytes")
|
||||||
self.content = content
|
self.content = content
|
||||||
self.uri = uri
|
self.uri = uri
|
||||||
|
self.error_details = ''
|
||||||
|
|
||||||
def _get_reason(self):
|
def _get_reason(self):
|
||||||
"""Calculate the reason for the error from the response content."""
|
"""Calculate the reason for the error from the response content."""
|
||||||
@ -54,9 +55,13 @@ class HttpError(Error):
|
|||||||
data = json.loads(self.content.decode('utf-8'))
|
data = json.loads(self.content.decode('utf-8'))
|
||||||
if isinstance(data, dict):
|
if isinstance(data, dict):
|
||||||
reason = data['error']['message']
|
reason = data['error']['message']
|
||||||
|
if 'details' in data['error']:
|
||||||
|
self.error_details = data['error']['details']
|
||||||
elif isinstance(data, list) and len(data) > 0:
|
elif isinstance(data, list) and len(data) > 0:
|
||||||
first_error = data[0]
|
first_error = data[0]
|
||||||
reason = first_error['error']['message']
|
reason = first_error['error']['message']
|
||||||
|
if 'details' in first_error['error']:
|
||||||
|
self.error_details = first_error['error']['details']
|
||||||
except (ValueError, KeyError, TypeError):
|
except (ValueError, KeyError, TypeError):
|
||||||
pass
|
pass
|
||||||
if reason is None:
|
if reason is None:
|
||||||
@ -64,7 +69,11 @@ class HttpError(Error):
|
|||||||
return reason
|
return reason
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
if self.uri:
|
reason = self._get_reason()
|
||||||
|
if self.error_details:
|
||||||
|
return '<HttpError %s when requesting %s returned "%s". Details: "%s">' % \
|
||||||
|
(self.resp.status, self.uri, reason.strip(), self.error_details)
|
||||||
|
elif self.uri:
|
||||||
return '<HttpError %s when requesting %s returned "%s">' % (
|
return '<HttpError %s when requesting %s returned "%s">' % (
|
||||||
self.resp.status, self.uri, self._get_reason().strip())
|
self.resp.status, self.uri, self._get_reason().strip())
|
||||||
else:
|
else:
|
||||||
|
@ -62,6 +62,7 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
from oauth2client import _helpers as util
|
from oauth2client import _helpers as util
|
||||||
|
|
||||||
|
from googleapiclient import _auth
|
||||||
from googleapiclient import mimeparse
|
from googleapiclient import mimeparse
|
||||||
from googleapiclient.errors import BatchError
|
from googleapiclient.errors import BatchError
|
||||||
from googleapiclient.errors import HttpError
|
from googleapiclient.errors import HttpError
|
||||||
@ -203,7 +204,7 @@ class MediaUploadProgress(object):
|
|||||||
the percentage complete as a float, returning 0.0 if the total size of
|
the percentage complete as a float, returning 0.0 if the total size of
|
||||||
the upload is unknown.
|
the upload is unknown.
|
||||||
"""
|
"""
|
||||||
if self.total_size is not None:
|
if self.total_size is not None and self.total_size != 0:
|
||||||
return float(self.resumable_progress) / float(self.total_size)
|
return float(self.resumable_progress) / float(self.total_size)
|
||||||
else:
|
else:
|
||||||
return 0.0
|
return 0.0
|
||||||
@ -229,7 +230,7 @@ class MediaDownloadProgress(object):
|
|||||||
the percentage complete as a float, returning 0.0 if the total size of
|
the percentage complete as a float, returning 0.0 if the total size of
|
||||||
the download is unknown.
|
the download is unknown.
|
||||||
"""
|
"""
|
||||||
if self.total_size is not None:
|
if self.total_size is not None and self.total_size != 0:
|
||||||
return float(self.resumable_progress) / float(self.total_size)
|
return float(self.resumable_progress) / float(self.total_size)
|
||||||
else:
|
else:
|
||||||
return 0.0
|
return 0.0
|
||||||
@ -1126,21 +1127,25 @@ class BatchHttpRequest(object):
|
|||||||
# If there is no http per the request then refresh the http passed in
|
# If there is no http per the request then refresh the http passed in
|
||||||
# via execute()
|
# via execute()
|
||||||
creds = None
|
creds = None
|
||||||
if request.http is not None and hasattr(request.http.request,
|
request_credentials = False
|
||||||
'credentials'):
|
|
||||||
creds = request.http.request.credentials
|
if request.http is not None:
|
||||||
elif http is not None and hasattr(http.request, 'credentials'):
|
creds = _auth.get_credentials_from_http(request.http)
|
||||||
creds = http.request.credentials
|
request_credentials = True
|
||||||
|
|
||||||
|
if creds is None and http is not None:
|
||||||
|
creds = _auth.get_credentials_from_http(http)
|
||||||
|
|
||||||
if creds is not None:
|
if creds is not None:
|
||||||
if id(creds) not in self._refreshed_credentials:
|
if id(creds) not in self._refreshed_credentials:
|
||||||
creds.refresh(http)
|
_auth.refresh_credentials(creds)
|
||||||
self._refreshed_credentials[id(creds)] = 1
|
self._refreshed_credentials[id(creds)] = 1
|
||||||
|
|
||||||
# Only apply the credentials if we are using the http object passed in,
|
# Only apply the credentials if we are using the http object passed in,
|
||||||
# otherwise apply() will get called during _serialize_request().
|
# otherwise apply() will get called during _serialize_request().
|
||||||
if request.http is None or not hasattr(request.http.request,
|
if request.http is None or not request_credentials:
|
||||||
'credentials'):
|
_auth.apply_credentials(creds, request.headers)
|
||||||
creds.apply(request.headers)
|
|
||||||
|
|
||||||
def _id_to_header(self, id_):
|
def _id_to_header(self, id_):
|
||||||
"""Convert an id to a Content-ID header value.
|
"""Convert an id to a Content-ID header value.
|
||||||
@ -1200,9 +1205,10 @@ class BatchHttpRequest(object):
|
|||||||
msg = MIMENonMultipart(major, minor)
|
msg = MIMENonMultipart(major, minor)
|
||||||
headers = request.headers.copy()
|
headers = request.headers.copy()
|
||||||
|
|
||||||
if request.http is not None and hasattr(request.http.request,
|
if request.http is not None:
|
||||||
'credentials'):
|
credentials = _auth.get_credentials_from_http(request.http)
|
||||||
request.http.request.credentials.apply(headers)
|
if credentials is not None:
|
||||||
|
_auth.apply_credentials(credentials, headers)
|
||||||
|
|
||||||
# MIMENonMultipart adds its own Content-Type header.
|
# MIMENonMultipart adds its own Content-Type header.
|
||||||
if 'content-type' in headers:
|
if 'content-type' in headers:
|
||||||
@ -1409,11 +1415,11 @@ class BatchHttpRequest(object):
|
|||||||
|
|
||||||
# Special case for OAuth2Credentials-style objects which have not yet been
|
# Special case for OAuth2Credentials-style objects which have not yet been
|
||||||
# refreshed with an initial access_token.
|
# refreshed with an initial access_token.
|
||||||
if getattr(http.request, 'credentials', None) is not None:
|
creds = _auth.get_credentials_from_http(http)
|
||||||
creds = http.request.credentials
|
if creds is not None:
|
||||||
if not getattr(creds, 'access_token', None):
|
if not _auth.is_valid(creds):
|
||||||
LOGGER.info('Attempting refresh to obtain initial access_token')
|
LOGGER.info('Attempting refresh to obtain initial access_token')
|
||||||
creds.refresh(http)
|
_auth.refresh_credentials(creds)
|
||||||
|
|
||||||
self._execute(http, self._order, self._requests)
|
self._execute(http, self._order, self._requests)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user