Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#1186: Revendor apitools as 'gcloud._apitools' #1189

Merged
merged 5 commits into from
Oct 23, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ omit =
*/demo/*
*/demo.py
*/_generated/*.py
# Exclude the forked code until tests are complete.
*/_apitools/*.py
exclude_lines =
# Re-enable the standard pragma
pragma: NO COVER
Expand Down
1 change: 1 addition & 0 deletions gcloud/_apitools/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Vendored-in for from google-apitools 0.4.11
59 changes: 59 additions & 0 deletions gcloud/_apitools/buffered_stream.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# pylint: skip-file
"""Small helper class to provide a small slice of a stream.

This class reads ahead to detect if we are at the end of the stream.
"""

from gcloud._apitools import exceptions


# TODO(user): Consider replacing this with a StringIO.
class BufferedStream(object):

"""Buffers a stream, reading ahead to determine if we're at the end."""

def __init__(self, stream, start, size):
self.__stream = stream
self.__start_pos = start
self.__buffer_pos = 0
self.__buffered_data = self.__stream.read(size)
self.__stream_at_end = len(self.__buffered_data) < size
self.__end_pos = self.__start_pos + len(self.__buffered_data)

def __str__(self):
return ('Buffered stream %s from position %s-%s with %s '
'bytes remaining' % (self.__stream, self.__start_pos,
self.__end_pos, self._bytes_remaining))

def __len__(self):
return len(self.__buffered_data)

@property
def stream_exhausted(self):
return self.__stream_at_end

@property
def stream_end_position(self):
return self.__end_pos

@property
def _bytes_remaining(self):
return len(self.__buffered_data) - self.__buffer_pos

def read(self, size=None): # pylint: disable=invalid-name
"""Reads from the buffer."""
if size is None or size < 0:
raise exceptions.NotYetImplementedError(
'Illegal read of size %s requested on BufferedStream. '
'Wrapped stream %s is at position %s-%s, '
'%s bytes remaining.' %
(size, self.__stream, self.__start_pos, self.__end_pos,
self._bytes_remaining))

data = ''
if self._bytes_remaining:
size = min(size, self._bytes_remaining)
data = self.__buffered_data[
self.__buffer_pos:self.__buffer_pos + size]
self.__buffer_pos += size
return data
148 changes: 148 additions & 0 deletions gcloud/_apitools/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# pylint: skip-file
"""Exceptions for generated client libraries."""


class Error(Exception):

"""Base class for all exceptions."""


class TypecheckError(Error, TypeError):

"""An object of an incorrect type is provided."""


class NotFoundError(Error):

"""A specified resource could not be found."""


class UserError(Error):

"""Base class for errors related to user input."""


class InvalidDataError(Error):

"""Base class for any invalid data error."""


class CommunicationError(Error):

"""Any communication error talking to an API server."""


class HttpError(CommunicationError):

"""Error making a request. Soon to be HttpError."""

def __init__(self, response, content, url):
super(HttpError, self).__init__()
self.response = response
self.content = content
self.url = url

def __str__(self):
content = self.content.decode('ascii', 'replace')
return 'HttpError accessing <%s>: response: <%s>, content <%s>' % (
self.url, self.response, content)

@property
def status_code(self):
# TODO(craigcitro): Turn this into something better than a
# KeyError if there is no status.
return int(self.response['status'])

@classmethod
def FromResponse(cls, http_response):
return cls(http_response.info, http_response.content,
http_response.request_url)


class InvalidUserInputError(InvalidDataError):

"""User-provided input is invalid."""


class InvalidDataFromServerError(InvalidDataError, CommunicationError):

"""Data received from the server is malformed."""


class BatchError(Error):

"""Error generated while constructing a batch request."""


class ConfigurationError(Error):

"""Base class for configuration errors."""


class GeneratedClientError(Error):

"""The generated client configuration is invalid."""


class ConfigurationValueError(UserError):

"""Some part of the user-specified client configuration is invalid."""


class ResourceUnavailableError(Error):

"""User requested an unavailable resource."""


class CredentialsError(Error):

"""Errors related to invalid credentials."""


class TransferError(CommunicationError):

"""Errors related to transfers."""


class TransferRetryError(TransferError):

"""Retryable errors related to transfers."""


class TransferInvalidError(TransferError):

"""The given transfer is invalid."""


class RequestError(CommunicationError):

"""The request was not successful."""


class RetryAfterError(HttpError):

"""The response contained a retry-after header."""

def __init__(self, response, content, url, retry_after):
super(RetryAfterError, self).__init__(response, content, url)
self.retry_after = int(retry_after)

@classmethod
def FromResponse(cls, http_response):
return cls(http_response.info, http_response.content,
http_response.request_url, http_response.retry_after)


class BadStatusCodeError(HttpError):

"""The request completed but returned a bad status code."""


class NotYetImplementedError(GeneratedClientError):

"""This functionality is not yet implemented."""


class StreamExhausted(Error):

"""Attempted to read more bytes from a stream than were available."""
Loading