From 37d409f9c1a5b79c0a5c479bd95ff9ad93ffe7b5 Mon Sep 17 00:00:00 2001 From: Chris Wilcox Date: Wed, 28 Nov 2018 19:54:48 -0800 Subject: [PATCH 1/4] blacken api_core and core --- api_core/google/__init__.py | 2 + api_core/google/api_core/__init__.py | 2 +- api_core/google/api_core/bidi.py | 89 ++--- api_core/google/api_core/datetime_helpers.py | 70 ++-- api_core/google/api_core/exceptions.py | 99 +++--- api_core/google/api_core/future/__init__.py | 4 +- api_core/google/api_core/future/_helpers.py | 2 +- api_core/google/api_core/future/polling.py | 9 +- api_core/google/api_core/gapic_v1/__init__.py | 7 +- .../google/api_core/gapic_v1/client_info.py | 30 +- api_core/google/api_core/gapic_v1/config.py | 54 ++- api_core/google/api_core/gapic_v1/method.py | 30 +- .../api_core/gapic_v1/routing_header.py | 7 +- api_core/google/api_core/general_helpers.py | 2 +- api_core/google/api_core/grpc_helpers.py | 63 ++-- api_core/google/api_core/operation.py | 68 ++-- .../google/api_core/operations_v1/__init__.py | 4 +- .../operations_v1/operations_client.py | 57 +-- .../operations_v1/operations_client_config.py | 21 +- api_core/google/api_core/page_iterator.py | 102 +++--- api_core/google/api_core/path_template.py | 49 ++- api_core/google/api_core/protobuf_helpers.py | 55 +-- api_core/google/api_core/retry.py | 77 ++-- api_core/google/api_core/timeout.py | 45 ++- api_core/noxfile.py | 69 ++-- api_core/setup.py | 76 ++-- api_core/tests/unit/future/test__helpers.py | 14 +- api_core/tests/unit/future/test_polling.py | 16 +- api_core/tests/unit/gapic/test_client_info.py | 40 +-- api_core/tests/unit/gapic/test_config.py | 72 ++-- api_core/tests/unit/gapic/test_method.py | 113 +++--- .../tests/unit/gapic/test_routing_header.py | 9 +- .../operations_v1/test_operations_client.py | 28 +- api_core/tests/unit/test_bidi.py | 99 +++--- api_core/tests/unit/test_datetime_helpers.py | 121 +++---- api_core/tests/unit/test_exceptions.py | 99 +++--- api_core/tests/unit/test_general_helpers.py | 2 - api_core/tests/unit/test_grpc_helpers.py | 256 +++++++------- api_core/tests/unit/test_operation.py | 82 +++-- api_core/tests/unit/test_page_iterator.py | 185 +++++----- api_core/tests/unit/test_path_template.py | 115 +++--- api_core/tests/unit/test_protobuf_helpers.py | 316 ++++++++--------- api_core/tests/unit/test_retry.py | 105 +++--- api_core/tests/unit/test_timeout.py | 37 +- core/google/__init__.py | 2 + core/google/cloud/__init__.py | 2 + core/google/cloud/_helpers.py | 117 +++--- core/google/cloud/_http.py | 86 +++-- core/google/cloud/_testing.py | 17 +- core/google/cloud/client.py | 58 +-- core/google/cloud/environment_vars.py | 10 +- core/google/cloud/iam.py | 55 +-- core/google/cloud/obsolete.py | 8 +- core/google/cloud/operation.py | 28 +- core/noxfile.py | 60 ++-- core/setup.py | 62 ++-- core/tests/unit/test__helpers.py | 334 ++++++++++-------- core/tests/unit/test__http.py | 235 ++++++------ core/tests/unit/test_client.py | 91 +++-- core/tests/unit/test_exceptions.py | 61 ++-- core/tests/unit/test_iam.py | 176 +++++---- core/tests/unit/test_obsolete.py | 8 +- core/tests/unit/test_operation.py | 92 ++--- 63 files changed, 2204 insertions(+), 2100 deletions(-) diff --git a/api_core/google/__init__.py b/api_core/google/__init__.py index e338417ca8c8..0d0a4c3ab273 100644 --- a/api_core/google/__init__.py +++ b/api_core/google/__init__.py @@ -16,7 +16,9 @@ try: import pkg_resources + pkg_resources.declare_namespace(__name__) except ImportError: import pkgutil + __path__ = pkgutil.extend_path(__path__, __name__) diff --git a/api_core/google/api_core/__init__.py b/api_core/google/api_core/__init__.py index 35d1238e6ff0..c762e18309db 100644 --- a/api_core/google/api_core/__init__.py +++ b/api_core/google/api_core/__init__.py @@ -20,4 +20,4 @@ from pkg_resources import get_distribution -__version__ = get_distribution('google-api-core').version +__version__ = get_distribution("google-api-core").version diff --git a/api_core/google/api_core/bidi.py b/api_core/google/api_core/bidi.py index 4d77ecc3d6c8..795a8d295f17 100644 --- a/api_core/google/api_core/bidi.py +++ b/api_core/google/api_core/bidi.py @@ -22,7 +22,7 @@ from google.api_core import exceptions _LOGGER = logging.getLogger(__name__) -_BIDIRECTIONAL_CONSUMER_NAME = 'Thread-ConsumeBidirectionalStream' +_BIDIRECTIONAL_CONSUMER_NAME = "Thread-ConsumeBidirectionalStream" class _RequestQueueGenerator(object): @@ -79,6 +79,7 @@ class _RequestQueueGenerator(object): easily restarting streams that require some initial configuration request. """ + def __init__(self, queue, period=1, initial_request=None): self._queue = queue self._period = period @@ -107,8 +108,8 @@ def __iter__(self): except queue.Empty: if not self._is_active(): _LOGGER.debug( - 'Empty queue and inactive call, exiting request ' - 'generator.') + "Empty queue and inactive call, exiting request " "generator." + ) return else: # call is still active, keep waiting for queue items. @@ -117,7 +118,7 @@ def __iter__(self): # The consumer explicitly sent "None", indicating that the request # should end. if item is None: - _LOGGER.debug('Cleanly exiting request generator.') + _LOGGER.debug("Cleanly exiting request generator.") return if not self._is_active(): @@ -125,8 +126,9 @@ def __iter__(self): # item back on the queue so that the next call can consume it. self._queue.put(item) _LOGGER.debug( - 'Inactive call, replacing item on queue and exiting ' - 'request generator.') + "Inactive call, replacing item on queue and exiting " + "request generator." + ) return yield item @@ -164,6 +166,7 @@ class BidiRpc(object): yield. This is useful if an initial request is needed to start the stream. """ + def __init__(self, start_rpc, initial_request=None): self._start_rpc = start_rpc self._initial_request = initial_request @@ -192,17 +195,18 @@ def _on_call_done(self, future): def open(self): """Opens the stream.""" if self.is_active: - raise ValueError('Can not open an already open stream.') + raise ValueError("Can not open an already open stream.") request_generator = _RequestQueueGenerator( - self._request_queue, initial_request=self._initial_request) + self._request_queue, initial_request=self._initial_request + ) call = self._start_rpc(iter(request_generator)) request_generator.call = call # TODO: api_core should expose the future interface for wrapped # callables as well. - if hasattr(call, '_wrapped'): # pragma: NO COVER + if hasattr(call, "_wrapped"): # pragma: NO COVER call._wrapped.add_done_callback(self._on_call_done) else: call.add_done_callback(self._on_call_done) @@ -232,8 +236,7 @@ def send(self, request): request (protobuf.Message): The request to send. """ if self.call is None: - raise ValueError( - 'Can not send() on an RPC that has never been open()ed.') + raise ValueError("Can not send() on an RPC that has never been open()ed.") # Don't use self.is_active(), as ResumableBidiRpc will overload it # to mean something semantically different. @@ -254,8 +257,7 @@ def recv(self): protobuf.Message: The received message. """ if self.call is None: - raise ValueError( - 'Can not recv() on an RPC that has never been open()ed.') + raise ValueError("Can not recv() on an RPC that has never been open()ed.") return next(self.call) @@ -309,6 +311,7 @@ def should_recover(exc): True if the stream should be recovered. This will be called whenever an error is encountered on the stream. """ + def __init__(self, start_rpc, should_recover, initial_request=None): super(ResumableBidiRpc, self).__init__(start_rpc, initial_request) self._should_recover = should_recover @@ -334,14 +337,14 @@ def _on_call_done(self, future): if not self._should_recover(future): self._finalize(future) else: - _LOGGER.debug('Re-opening stream from gRPC callback.') + _LOGGER.debug("Re-opening stream from gRPC callback.") self._reopen() def _reopen(self): with self._operational_lock: # Another thread already managed to re-open this stream. if self.call is not None and self.call.is_active(): - _LOGGER.debug('Stream was already re-established.') + _LOGGER.debug("Stream was already re-established.") return self.call = None @@ -362,11 +365,11 @@ def _reopen(self): # If re-opening or re-calling the method fails for any reason, # consider it a terminal error and finalize the stream. except Exception as exc: - _LOGGER.debug('Failed to re-open stream due to %s', exc) + _LOGGER.debug("Failed to re-open stream due to %s", exc) self._finalize(exc) raise - _LOGGER.info('Re-established stream') + _LOGGER.info("Re-established stream") def _recoverable(self, method, *args, **kwargs): """Wraps a method to recover the stream and retry on error. @@ -388,18 +391,15 @@ def _recoverable(self, method, *args, **kwargs): except Exception as exc: with self._operational_lock: - _LOGGER.debug( - 'Call to retryable %r caused %s.', method, exc) + _LOGGER.debug("Call to retryable %r caused %s.", method, exc) if not self._should_recover(exc): self.close() - _LOGGER.debug( - 'Not retrying %r due to %s.', method, exc) + _LOGGER.debug("Not retrying %r due to %s.", method, exc) self._finalize(exc) raise exc - _LOGGER.debug( - 'Re-opening stream from retryable %r.', method) + _LOGGER.debug("Re-opening stream from retryable %r.", method) self._reopen() def _send(self, request): @@ -414,8 +414,7 @@ def _send(self, request): call = self.call if call is None: - raise ValueError( - 'Can not send() on an RPC that has never been open()ed.') + raise ValueError("Can not send() on an RPC that has never been open()ed.") # Don't use self.is_active(), as ResumableBidiRpc will overload it # to mean something semantically different. @@ -434,8 +433,7 @@ def _recv(self): call = self.call if call is None: - raise ValueError( - 'Can not recv() on an RPC that has never been open()ed.') + raise ValueError("Can not recv() on an RPC that has never been open()ed.") return next(call) @@ -493,6 +491,7 @@ def on_response(response): on_response (Callable[[protobuf.Message], None]): The callback to be called for every response on the stream. """ + def __init__(self, bidi_rpc, on_response): self._bidi_rpc = bidi_rpc self._on_response = on_response @@ -522,43 +521,47 @@ def _thread_main(self): # Python 2.7. with self._wake: if self._paused: - _LOGGER.debug('paused, waiting for waking.') + _LOGGER.debug("paused, waiting for waking.") self._wake.wait() - _LOGGER.debug('woken.') + _LOGGER.debug("woken.") - _LOGGER.debug('waiting for recv.') + _LOGGER.debug("waiting for recv.") response = self._bidi_rpc.recv() - _LOGGER.debug('recved response.') + _LOGGER.debug("recved response.") self._on_response(response) except exceptions.GoogleAPICallError as exc: _LOGGER.debug( - '%s caught error %s and will exit. Generally this is due to ' - 'the RPC itself being cancelled and the error will be ' - 'surfaced to the calling code.', - _BIDIRECTIONAL_CONSUMER_NAME, exc, exc_info=True) + "%s caught error %s and will exit. Generally this is due to " + "the RPC itself being cancelled and the error will be " + "surfaced to the calling code.", + _BIDIRECTIONAL_CONSUMER_NAME, + exc, + exc_info=True, + ) except Exception as exc: _LOGGER.exception( - '%s caught unexpected exception %s and will exit.', - _BIDIRECTIONAL_CONSUMER_NAME, exc) + "%s caught unexpected exception %s and will exit.", + _BIDIRECTIONAL_CONSUMER_NAME, + exc, + ) else: - _LOGGER.error( - 'The bidirectional RPC exited.') + _LOGGER.error("The bidirectional RPC exited.") - _LOGGER.info('%s exiting', _BIDIRECTIONAL_CONSUMER_NAME) + _LOGGER.info("%s exiting", _BIDIRECTIONAL_CONSUMER_NAME) def start(self): """Start the background thread and begin consuming the thread.""" with self._operational_lock: thread = threading.Thread( - name=_BIDIRECTIONAL_CONSUMER_NAME, - target=self._thread_main) + name=_BIDIRECTIONAL_CONSUMER_NAME, target=self._thread_main + ) thread.daemon = True thread.start() self._thread = thread - _LOGGER.debug('Started helper thread %s', thread.name) + _LOGGER.debug("Started helper thread %s", thread.name) def stop(self): """Stop consuming the stream and shutdown the background thread.""" diff --git a/api_core/google/api_core/datetime_helpers.py b/api_core/google/api_core/datetime_helpers.py index 393d2d6c612a..3f3523bfd866 100644 --- a/api_core/google/api_core/datetime_helpers.py +++ b/api_core/google/api_core/datetime_helpers.py @@ -22,10 +22,11 @@ _UTC_EPOCH = datetime.datetime.utcfromtimestamp(0).replace(tzinfo=pytz.utc) -_RFC3339_MICROS = '%Y-%m-%dT%H:%M:%S.%fZ' -_RFC3339_NO_FRACTION = '%Y-%m-%dT%H:%M:%S' +_RFC3339_MICROS = "%Y-%m-%dT%H:%M:%S.%fZ" +_RFC3339_NO_FRACTION = "%Y-%m-%dT%H:%M:%S" # datetime.strptime cannot handle nanosecond precision: parse w/ regex -_RFC3339_NANOS = re.compile(r""" +_RFC3339_NANOS = re.compile( + r""" (?P \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2} # YYYY-MM-DDTHH:MM:SS ) @@ -34,7 +35,9 @@ (?P\d{1,9}) # nanoseconds, maybe truncated )? Z # Zulu -""", re.VERBOSE) +""", + re.VERBOSE, +) def utcnow(): @@ -94,7 +97,7 @@ def from_iso8601_date(value): Returns: datetime.date: A date equivalent to the date string. """ - return datetime.datetime.strptime(value, '%Y-%m-%d').date() + return datetime.datetime.strptime(value, "%Y-%m-%d").date() def from_iso8601_time(value): @@ -106,7 +109,7 @@ def from_iso8601_time(value): Returns: datetime.time: A time equivalent to the time string. """ - return datetime.datetime.strptime(value, '%H:%M:%S').time() + return datetime.datetime.strptime(value, "%H:%M:%S").time() def from_rfc3339(value): @@ -119,8 +122,7 @@ def from_rfc3339(value): datetime.datetime: The datetime object equivalent to the timestamp in UTC. """ - return datetime.datetime.strptime( - value, _RFC3339_MICROS).replace(tzinfo=pytz.utc) + return datetime.datetime.strptime(value, _RFC3339_MICROS).replace(tzinfo=pytz.utc) def from_rfc3339_nanos(value): @@ -145,12 +147,15 @@ def from_rfc3339_nanos(value): if with_nanos is None: raise ValueError( - 'Timestamp: {!r}, does not match pattern: {!r}'.format( - value, _RFC3339_NANOS.pattern)) + "Timestamp: {!r}, does not match pattern: {!r}".format( + value, _RFC3339_NANOS.pattern + ) + ) bare_seconds = datetime.datetime.strptime( - with_nanos.group('no_fraction'), _RFC3339_NO_FRACTION) - fraction = with_nanos.group('nanos') + with_nanos.group("no_fraction"), _RFC3339_NO_FRACTION + ) + fraction = with_nanos.group("nanos") if fraction is None: micros = 0 @@ -186,19 +191,20 @@ class DatetimeWithNanoseconds(datetime.datetime): Nanosecond can be passed only as a keyword argument. """ - __slots__ = ('_nanosecond',) + + __slots__ = ("_nanosecond",) # pylint: disable=arguments-differ def __new__(cls, *args, **kw): - nanos = kw.pop('nanosecond', 0) + nanos = kw.pop("nanosecond", 0) if nanos > 0: - if 'microsecond' in kw: - raise TypeError( - "Specify only one of 'microsecond' or 'nanosecond'") - kw['microsecond'] = nanos // 1000 + if "microsecond" in kw: + raise TypeError("Specify only one of 'microsecond' or 'nanosecond'") + kw["microsecond"] = nanos // 1000 inst = datetime.datetime.__new__(cls, *args, **kw) inst._nanosecond = nanos or 0 return inst + # pylint: disable=arguments-differ @property @@ -214,8 +220,8 @@ def rfc3339(self): """ if self._nanosecond == 0: return to_rfc3339(self) - nanos = str(self._nanosecond).rstrip('0') - return '{}.{}Z'.format(self.strftime(_RFC3339_NO_FRACTION), nanos) + nanos = str(self._nanosecond).rstrip("0") + return "{}.{}Z".format(self.strftime(_RFC3339_NO_FRACTION), nanos) @classmethod def from_rfc3339(cls, stamp): @@ -234,16 +240,26 @@ def from_rfc3339(cls, stamp): with_nanos = _RFC3339_NANOS.match(stamp) if with_nanos is None: raise ValueError( - 'Timestamp: {}, does not match pattern: {}'.format( - stamp, _RFC3339_NANOS.pattern)) + "Timestamp: {}, does not match pattern: {}".format( + stamp, _RFC3339_NANOS.pattern + ) + ) bare = datetime.datetime.strptime( - with_nanos.group('no_fraction'), _RFC3339_NO_FRACTION) - fraction = with_nanos.group('nanos') + with_nanos.group("no_fraction"), _RFC3339_NO_FRACTION + ) + fraction = with_nanos.group("nanos") if fraction is None: nanos = 0 else: scale = 9 - len(fraction) nanos = int(fraction) * (10 ** scale) - return cls(bare.year, bare.month, bare.day, - bare.hour, bare.minute, bare.second, - nanosecond=nanos, tzinfo=pytz.UTC) + return cls( + bare.year, + bare.month, + bare.day, + bare.hour, + bare.minute, + bare.second, + nanosecond=nanos, + tzinfo=pytz.UTC, + ) diff --git a/api_core/google/api_core/exceptions.py b/api_core/google/api_core/exceptions.py index 5cd5ea97afb8..eed4ee40eee5 100644 --- a/api_core/google/api_core/exceptions.py +++ b/api_core/google/api_core/exceptions.py @@ -37,6 +37,7 @@ class GoogleAPIError(Exception): """Base class for all exceptions raised by Google API Clients.""" + pass @@ -49,6 +50,7 @@ class RetryError(GoogleAPIError): cause (Exception): The last exception raised when retring the function. """ + def __init__(self, message, cause): super(RetryError, self).__init__(message) self.message = message @@ -60,11 +62,12 @@ def cause(self): return self._cause def __str__(self): - return '{}, last exception: {}'.format(self.message, self.cause) + return "{}, last exception: {}".format(self.message, self.cause) class _GoogleAPICallErrorMeta(type): """Metaclass for registering GoogleAPICallError subclasses.""" + def __new__(mcs, name, bases, class_dict): cls = type.__new__(mcs, name, bases, class_dict) if cls.code is not None: @@ -110,7 +113,7 @@ def __init__(self, message, errors=(), response=None): self._response = response def __str__(self): - return '{} {}'.format(self.code, self.message) + return "{} {}".format(self.code, self.message) @property def errors(self): @@ -134,16 +137,19 @@ class Redirection(GoogleAPICallError): class MovedPermanently(Redirection): """Exception mapping a ``301 Moved Permanently`` response.""" + code = http_client.MOVED_PERMANENTLY class NotModified(Redirection): """Exception mapping a ``304 Not Modified`` response.""" + code = http_client.NOT_MODIFIED class TemporaryRedirect(Redirection): """Exception mapping a ``307 Temporary Redirect`` response.""" + code = http_client.TEMPORARY_REDIRECT @@ -153,6 +159,7 @@ class ResumeIncomplete(Redirection): .. note:: :attr:`http_client.PERMANENT_REDIRECT` is ``308``, but Google APIs differ in their use of this status code. """ + code = 308 @@ -162,109 +169,119 @@ class ClientError(GoogleAPICallError): class BadRequest(ClientError): """Exception mapping a ``400 Bad Request`` response.""" + code = http_client.BAD_REQUEST class InvalidArgument(BadRequest): """Exception mapping a :attr:`grpc.StatusCode.INVALID_ARGUMENT` error.""" - grpc_status_code = ( - grpc.StatusCode.INVALID_ARGUMENT if grpc is not None else None) + + grpc_status_code = grpc.StatusCode.INVALID_ARGUMENT if grpc is not None else None class FailedPrecondition(BadRequest): """Exception mapping a :attr:`grpc.StatusCode.FAILED_PRECONDITION` error.""" - grpc_status_code = ( - grpc.StatusCode.FAILED_PRECONDITION if grpc is not None else None) + + grpc_status_code = grpc.StatusCode.FAILED_PRECONDITION if grpc is not None else None class OutOfRange(BadRequest): """Exception mapping a :attr:`grpc.StatusCode.OUT_OF_RANGE` error.""" - grpc_status_code = ( - grpc.StatusCode.OUT_OF_RANGE if grpc is not None else None) + + grpc_status_code = grpc.StatusCode.OUT_OF_RANGE if grpc is not None else None class Unauthorized(ClientError): """Exception mapping a ``401 Unauthorized`` response.""" + code = http_client.UNAUTHORIZED class Unauthenticated(Unauthorized): """Exception mapping a :attr:`grpc.StatusCode.UNAUTHENTICATED` error.""" - grpc_status_code = ( - grpc.StatusCode.UNAUTHENTICATED if grpc is not None else None) + + grpc_status_code = grpc.StatusCode.UNAUTHENTICATED if grpc is not None else None class Forbidden(ClientError): """Exception mapping a ``403 Forbidden`` response.""" + code = http_client.FORBIDDEN class PermissionDenied(Forbidden): """Exception mapping a :attr:`grpc.StatusCode.PERMISSION_DENIED` error.""" - grpc_status_code = ( - grpc.StatusCode.PERMISSION_DENIED if grpc is not None else None) + + grpc_status_code = grpc.StatusCode.PERMISSION_DENIED if grpc is not None else None class NotFound(ClientError): """Exception mapping a ``404 Not Found`` response or a :attr:`grpc.StatusCode.NOT_FOUND` error.""" + code = http_client.NOT_FOUND - grpc_status_code = ( - grpc.StatusCode.NOT_FOUND if grpc is not None else None) + grpc_status_code = grpc.StatusCode.NOT_FOUND if grpc is not None else None class MethodNotAllowed(ClientError): """Exception mapping a ``405 Method Not Allowed`` response.""" + code = http_client.METHOD_NOT_ALLOWED class Conflict(ClientError): """Exception mapping a ``409 Conflict`` response.""" + code = http_client.CONFLICT class AlreadyExists(Conflict): """Exception mapping a :attr:`grpc.StatusCode.ALREADY_EXISTS` error.""" - grpc_status_code = ( - grpc.StatusCode.ALREADY_EXISTS if grpc is not None else None) + + grpc_status_code = grpc.StatusCode.ALREADY_EXISTS if grpc is not None else None class Aborted(Conflict): """Exception mapping a :attr:`grpc.StatusCode.ABORTED` error.""" - grpc_status_code = ( - grpc.StatusCode.ABORTED if grpc is not None else None) + + grpc_status_code = grpc.StatusCode.ABORTED if grpc is not None else None class LengthRequired(ClientError): """Exception mapping a ``411 Length Required`` response.""" + code = http_client.LENGTH_REQUIRED class PreconditionFailed(ClientError): """Exception mapping a ``412 Precondition Failed`` response.""" + code = http_client.PRECONDITION_FAILED class RequestRangeNotSatisfiable(ClientError): """Exception mapping a ``416 Request Range Not Satisfiable`` response.""" + code = http_client.REQUESTED_RANGE_NOT_SATISFIABLE class TooManyRequests(ClientError): """Exception mapping a ``429 Too Many Requests`` response.""" + # http_client does not define a constant for this in Python 2. code = 429 class ResourceExhausted(TooManyRequests): """Exception mapping a :attr:`grpc.StatusCode.RESOURCE_EXHAUSTED` error.""" - grpc_status_code = ( - grpc.StatusCode.RESOURCE_EXHAUSTED if grpc is not None else None) + + grpc_status_code = grpc.StatusCode.RESOURCE_EXHAUSTED if grpc is not None else None class Cancelled(ClientError): """Exception mapping a :attr:`grpc.StatusCode.CANCELLED` error.""" + # This maps to HTTP status code 499. See # https://github.com/googleapis/googleapis/blob/master/google/rpc\ # /code.proto @@ -279,50 +296,55 @@ class ServerError(GoogleAPICallError): class InternalServerError(ServerError): """Exception mapping a ``500 Internal Server Error`` response. or a :attr:`grpc.StatusCode.INTERNAL` error.""" + code = http_client.INTERNAL_SERVER_ERROR grpc_status_code = grpc.StatusCode.INTERNAL if grpc is not None else None class Unknown(ServerError): """Exception mapping a :attr:`grpc.StatusCode.UNKNOWN` error.""" + grpc_status_code = grpc.StatusCode.UNKNOWN if grpc is not None else None class DataLoss(ServerError): """Exception mapping a :attr:`grpc.StatusCode.DATA_LOSS` error.""" + grpc_status_code = grpc.StatusCode.DATA_LOSS if grpc is not None else None class MethodNotImplemented(ServerError): """Exception mapping a ``501 Not Implemented`` response or a :attr:`grpc.StatusCode.UNIMPLEMENTED` error.""" + code = http_client.NOT_IMPLEMENTED - grpc_status_code = ( - grpc.StatusCode.UNIMPLEMENTED if grpc is not None else None) + grpc_status_code = grpc.StatusCode.UNIMPLEMENTED if grpc is not None else None class BadGateway(ServerError): """Exception mapping a ``502 Bad Gateway`` response.""" + code = http_client.BAD_GATEWAY class ServiceUnavailable(ServerError): """Exception mapping a ``503 Service Unavailable`` response or a :attr:`grpc.StatusCode.UNAVAILABLE` error.""" + code = http_client.SERVICE_UNAVAILABLE - grpc_status_code = ( - grpc.StatusCode.UNAVAILABLE if grpc is not None else None) + grpc_status_code = grpc.StatusCode.UNAVAILABLE if grpc is not None else None class GatewayTimeout(ServerError): """Exception mapping a ``504 Gateway Timeout`` response.""" + code = http_client.GATEWAY_TIMEOUT class DeadlineExceeded(GatewayTimeout): """Exception mapping a :attr:`grpc.StatusCode.DEADLINE_EXCEEDED` error.""" - grpc_status_code = ( - grpc.StatusCode.DEADLINE_EXCEEDED if grpc is not None else None) + + grpc_status_code = grpc.StatusCode.DEADLINE_EXCEEDED if grpc is not None else None def exception_class_for_http_status(status_code): @@ -373,18 +395,18 @@ def from_http_response(response): try: payload = response.json() except ValueError: - payload = {'error': {'message': response.text or 'unknown error'}} + payload = {"error": {"message": response.text or "unknown error"}} - error_message = payload.get('error', {}).get('message', 'unknown error') - errors = payload.get('error', {}).get('errors', ()) + error_message = payload.get("error", {}).get("message", "unknown error") + errors = payload.get("error", {}).get("errors", ()) - message = u'{method} {url}: {error}'.format( - method=response.request.method, - url=response.request.url, - error=error_message) + message = "{method} {url}: {error}".format( + method=response.request.method, url=response.request.url, error=error_message + ) exception = from_http_status( - response.status_code, message, errors=errors, response=response) + response.status_code, message, errors=errors, response=response + ) return exception @@ -434,10 +456,7 @@ def from_grpc_error(rpc_exc): """ if isinstance(rpc_exc, grpc.Call): return from_grpc_status( - rpc_exc.code(), - rpc_exc.details(), - errors=(rpc_exc,), - response=rpc_exc) + rpc_exc.code(), rpc_exc.details(), errors=(rpc_exc,), response=rpc_exc + ) else: - return GoogleAPICallError( - str(rpc_exc), errors=(rpc_exc,), response=rpc_exc) + return GoogleAPICallError(str(rpc_exc), errors=(rpc_exc,), response=rpc_exc) diff --git a/api_core/google/api_core/future/__init__.py b/api_core/google/api_core/future/__init__.py index 8c75da712756..3768b2c53f53 100644 --- a/api_core/google/api_core/future/__init__.py +++ b/api_core/google/api_core/future/__init__.py @@ -16,6 +16,4 @@ from google.api_core.future.base import Future -__all__ = [ - 'Future', -] +__all__ = ["Future"] diff --git a/api_core/google/api_core/future/_helpers.py b/api_core/google/api_core/future/_helpers.py index 2f0136a9f108..9e88ca9d561d 100644 --- a/api_core/google/api_core/future/_helpers.py +++ b/api_core/google/api_core/future/_helpers.py @@ -36,4 +36,4 @@ def safe_invoke_callback(callback, *args, **kwargs): try: return callback(*args, **kwargs) except Exception: - _LOGGER.exception('Error while executing Future callback.') + _LOGGER.exception("Error while executing Future callback.") diff --git a/api_core/google/api_core/future/polling.py b/api_core/google/api_core/future/polling.py index 01adc21a09eb..5c16c49f67f6 100644 --- a/api_core/google/api_core/future/polling.py +++ b/api_core/google/api_core/future/polling.py @@ -25,6 +25,7 @@ class _OperationNotComplete(Exception): """Private exception used for polling via retry.""" + pass @@ -52,6 +53,7 @@ class PollingFuture(base.Future): is polled. Regardless of the retry's ``deadline``, it will be overridden by the ``timeout`` argument to :meth:`result`. """ + def __init__(self, retry=DEFAULT_RETRY): super(PollingFuture, self).__init__() self._retry = retry @@ -99,8 +101,8 @@ def _blocking_poll(self, timeout=None): retry_(self._done_or_raise)() except exceptions.RetryError: raise concurrent.futures.TimeoutError( - 'Operation did not complete within the designated ' - 'timeout.') + "Operation did not complete within the designated " "timeout." + ) def result(self, timeout=None): """Get the result of the operation, blocking if necessary. @@ -160,7 +162,8 @@ def add_done_callback(self, fn): # The polling thread will exit on its own as soon as the operation # is done. self._polling_thread = _helpers.start_daemon_thread( - target=self._blocking_poll) + target=self._blocking_poll + ) def _invoke_callbacks(self, *args, **kwargs): """Invoke all done callbacks.""" diff --git a/api_core/google/api_core/gapic_v1/__init__.py b/api_core/google/api_core/gapic_v1/__init__.py index 88270d854f08..e7a7a686f58e 100644 --- a/api_core/google/api_core/gapic_v1/__init__.py +++ b/api_core/google/api_core/gapic_v1/__init__.py @@ -17,9 +17,4 @@ from google.api_core.gapic_v1 import method from google.api_core.gapic_v1 import routing_header -__all__ = [ - 'client_info', - 'config', - 'method', - 'routing_header', -] +__all__ = ["client_info", "config", "method", "routing_header"] diff --git a/api_core/google/api_core/gapic_v1/client_info.py b/api_core/google/api_core/gapic_v1/client_info.py index 7feeaf1eaae1..66a4e4cabae0 100644 --- a/api_core/google/api_core/gapic_v1/client_info.py +++ b/api_core/google/api_core/gapic_v1/client_info.py @@ -23,14 +23,14 @@ import pkg_resources _PY_VERSION = platform.python_version() -_API_CORE_VERSION = pkg_resources.get_distribution('google-api-core').version +_API_CORE_VERSION = pkg_resources.get_distribution("google-api-core").version try: - _GRPC_VERSION = pkg_resources.get_distribution('grpcio').version + _GRPC_VERSION = pkg_resources.get_distribution("grpcio").version except pkg_resources.DistributionNotFound: # pragma: NO COVER _GRPC_VERSION = None -METRICS_METADATA_KEY = 'x-goog-api-client' +METRICS_METADATA_KEY = "x-goog-api-client" class ClientInfo(object): @@ -52,13 +52,15 @@ class ClientInfo(object): by gapic or if additional functionality was built on top of a gapic client library. """ + def __init__( - self, - python_version=_PY_VERSION, - grpc_version=_GRPC_VERSION, - api_core_version=_API_CORE_VERSION, - gapic_version=None, - client_library_version=None): + self, + python_version=_PY_VERSION, + grpc_version=_GRPC_VERSION, + api_core_version=_API_CORE_VERSION, + gapic_version=None, + client_library_version=None, + ): self.python_version = python_version self.grpc_version = grpc_version self.api_core_version = api_core_version @@ -69,18 +71,18 @@ def to_user_agent(self): """Returns the user-agent string for this client info.""" # Note: the order here is important as the internal metrics system # expects these items to be in specific locations. - ua = 'gl-python/{python_version} ' + ua = "gl-python/{python_version} " if self.grpc_version is not None: - ua += 'grpc/{grpc_version} ' + ua += "grpc/{grpc_version} " - ua += 'gax/{api_core_version} ' + ua += "gax/{api_core_version} " if self.gapic_version is not None: - ua += 'gapic/{gapic_version} ' + ua += "gapic/{gapic_version} " if self.client_library_version is not None: - ua += 'gccl/{client_library_version} ' + ua += "gccl/{client_library_version} " return ua.format(**self.__dict__).strip() diff --git a/api_core/google/api_core/gapic_v1/config.py b/api_core/google/api_core/gapic_v1/config.py index e8bb47b449ad..3a3eb15fdd44 100644 --- a/api_core/google/api_core/gapic_v1/config.py +++ b/api_core/google/api_core/gapic_v1/config.py @@ -42,8 +42,7 @@ def _exception_class_for_grpc_status_name(name): :func:`type`: The appropriate subclass of :class:`google.api_core.exceptions.GoogleAPICallError`. """ - return exceptions.exception_class_for_grpc_status( - getattr(grpc.StatusCode, name)) + return exceptions.exception_class_for_grpc_status(getattr(grpc.StatusCode, name)) def _retry_from_retry_config(retry_params, retry_codes): @@ -69,15 +68,15 @@ def _retry_from_retry_config(retry_params, retry_codes): google.api_core.retry.Retry: The default retry object for the method. """ exception_classes = [ - _exception_class_for_grpc_status_name(code) for code in retry_codes] + _exception_class_for_grpc_status_name(code) for code in retry_codes + ] return retry.Retry( retry.if_exception_type(*exception_classes), - initial=( - retry_params['initial_retry_delay_millis'] / _MILLIS_PER_SECOND), - maximum=( - retry_params['max_retry_delay_millis'] / _MILLIS_PER_SECOND), - multiplier=retry_params['retry_delay_multiplier'], - deadline=retry_params['total_timeout_millis'] / _MILLIS_PER_SECOND) + initial=(retry_params["initial_retry_delay_millis"] / _MILLIS_PER_SECOND), + maximum=(retry_params["max_retry_delay_millis"] / _MILLIS_PER_SECOND), + multiplier=retry_params["retry_delay_multiplier"], + deadline=retry_params["total_timeout_millis"] / _MILLIS_PER_SECOND, + ) def _timeout_from_retry_config(retry_params): @@ -101,16 +100,14 @@ def _timeout_from_retry_config(retry_params): the method. """ return timeout.ExponentialTimeout( - initial=( - retry_params['initial_rpc_timeout_millis'] / _MILLIS_PER_SECOND), - maximum=( - retry_params['max_rpc_timeout_millis'] / _MILLIS_PER_SECOND), - multiplier=retry_params['rpc_timeout_multiplier'], - deadline=( - retry_params['total_timeout_millis'] / _MILLIS_PER_SECOND)) + initial=(retry_params["initial_rpc_timeout_millis"] / _MILLIS_PER_SECOND), + maximum=(retry_params["max_rpc_timeout_millis"] / _MILLIS_PER_SECOND), + multiplier=retry_params["rpc_timeout_multiplier"], + deadline=(retry_params["total_timeout_millis"] / _MILLIS_PER_SECOND), + ) -MethodConfig = collections.namedtuple('MethodConfig', ['retry', 'timeout']) +MethodConfig = collections.namedtuple("MethodConfig", ["retry", "timeout"]) def parse_method_configs(interface_config): @@ -131,15 +128,15 @@ def parse_method_configs(interface_config): # Grab all the retry codes retry_codes_map = { name: retry_codes - for name, retry_codes - in six.iteritems(interface_config.get('retry_codes', {})) + for name, retry_codes in six.iteritems(interface_config.get("retry_codes", {})) } # Grab all of the retry params retry_params_map = { name: retry_params - for name, retry_params - in six.iteritems(interface_config.get('retry_params', {})) + for name, retry_params in six.iteritems( + interface_config.get("retry_params", {}) + ) } # Iterate through all the API methods and create a flat MethodConfig @@ -147,23 +144,24 @@ def parse_method_configs(interface_config): method_configs = {} for method_name, method_params in six.iteritems( - interface_config.get('methods', {})): - retry_params_name = method_params.get('retry_params_name') + interface_config.get("methods", {}) + ): + retry_params_name = method_params.get("retry_params_name") if retry_params_name is not None: retry_params = retry_params_map[retry_params_name] retry_ = _retry_from_retry_config( - retry_params, - retry_codes_map[method_params['retry_codes_name']]) + retry_params, retry_codes_map[method_params["retry_codes_name"]] + ) timeout_ = _timeout_from_retry_config(retry_params) # No retry config, so this is a non-retryable method. else: retry_ = None timeout_ = timeout.ConstantTimeout( - method_params['timeout_millis'] / _MILLIS_PER_SECOND) + method_params["timeout_millis"] / _MILLIS_PER_SECOND + ) - method_configs[method_name] = MethodConfig( - retry=retry_, timeout=timeout_) + method_configs[method_name] = MethodConfig(retry=retry_, timeout=timeout_) return method_configs diff --git a/api_core/google/api_core/gapic_v1/method.py b/api_core/google/api_core/gapic_v1/method.py index 9c4cf032b471..49982c0306cb 100644 --- a/api_core/google/api_core/gapic_v1/method.py +++ b/api_core/google/api_core/gapic_v1/method.py @@ -69,8 +69,11 @@ def _determine_timeout(default_timeout, specified_timeout, retry): # a non-default retry is specified, make sure the timeout's deadline # matches the retry's. This handles the case where the user leaves # the timeout default but specifies a lower deadline via the retry. - if (retry and retry is not DEFAULT - and isinstance(default_timeout, timeout.ExponentialTimeout)): + if ( + retry + and retry is not DEFAULT + and isinstance(default_timeout, timeout.ExponentialTimeout) + ): return default_timeout.with_deadline(retry._deadline) else: return default_timeout @@ -111,13 +114,14 @@ def __call__(self, *args, **kwargs): # extract the retry and timeout params. timeout_ = _determine_timeout( self._timeout, - kwargs.pop('timeout', self._timeout), + kwargs.pop("timeout", self._timeout), # Use only the invocation-specified retry only for this, as we only # want to adjust the timeout deadline if the *user* specified # a different retry. - kwargs.get('retry', None)) + kwargs.get("retry", None), + ) - retry = kwargs.pop('retry', self._retry) + retry = kwargs.pop("retry", self._retry) if retry is DEFAULT: retry = self._retry @@ -127,21 +131,24 @@ def __call__(self, *args, **kwargs): # Add the user agent metadata to the call. if self._metadata is not None: - metadata = kwargs.get('metadata', []) + metadata = kwargs.get("metadata", []) # Due to the nature of invocation, None should be treated the same # as not specified. if metadata is None: metadata = [] metadata = list(metadata) metadata.extend(self._metadata) - kwargs['metadata'] = metadata + kwargs["metadata"] = metadata return wrapped_func(*args, **kwargs) def wrap_method( - func, default_retry=None, default_timeout=None, - client_info=client_info.DEFAULT_CLIENT_INFO): + func, + default_retry=None, + default_timeout=None, + client_info=client_info.DEFAULT_CLIENT_INFO, +): """Wrap an RPC method with common behavior. This applies common error wrapping, retry, and timeout behavior a function. @@ -230,5 +237,6 @@ def get_topic(name, timeout=None): return general_helpers.wraps(func)( _GapicCallable( - func, default_retry, default_timeout, - metadata=user_agent_metadata)) + func, default_retry, default_timeout, metadata=user_agent_metadata + ) + ) diff --git a/api_core/google/api_core/gapic_v1/routing_header.py b/api_core/google/api_core/gapic_v1/routing_header.py index fc88bb6a6c2d..3fb12a6f8e26 100644 --- a/api_core/google/api_core/gapic_v1/routing_header.py +++ b/api_core/google/api_core/gapic_v1/routing_header.py @@ -24,7 +24,7 @@ from six.moves.urllib.parse import urlencode -ROUTING_METADATA_KEY = 'x-goog-request-params' +ROUTING_METADATA_KEY = "x-goog-request-params" def to_routing_header(params): @@ -39,11 +39,12 @@ def to_routing_header(params): """ if sys.version_info[0] < 3: # Python 2 does not have the "safe" parameter for urlencode. - return urlencode(params).replace('%2F', '/') + return urlencode(params).replace("%2F", "/") return urlencode( params, # Per Google API policy (go/api-url-encoding), / is not encoded. - safe='/') + safe="/", + ) def to_grpc_metadata(params): diff --git a/api_core/google/api_core/general_helpers.py b/api_core/google/api_core/general_helpers.py index 2c23a5a6a7ea..5661663ba984 100644 --- a/api_core/google/api_core/general_helpers.py +++ b/api_core/google/api_core/general_helpers.py @@ -21,7 +21,7 @@ # functools.partial objects lack several attributes present on real function # objects. In Python 2 wraps fails on this so use a restricted set instead. -_PARTIAL_VALID_ASSIGNMENTS = ('__doc__',) +_PARTIAL_VALID_ASSIGNMENTS = ("__doc__",) def wraps(wrapped): diff --git a/api_core/google/api_core/grpc_helpers.py b/api_core/google/api_core/grpc_helpers.py index b4ac9e0750ec..4d63beb36910 100644 --- a/api_core/google/api_core/grpc_helpers.py +++ b/api_core/google/api_core/grpc_helpers.py @@ -28,15 +28,13 @@ try: import grpc_gcp + HAS_GRPC_GCP = True except ImportError: HAS_GRPC_GCP = False # The list of gRPC Callable interfaces that return iterators. -_STREAM_WRAP_CLASSES = ( - grpc.UnaryStreamMultiCallable, - grpc.StreamStreamMultiCallable, -) +_STREAM_WRAP_CLASSES = (grpc.UnaryStreamMultiCallable, grpc.StreamStreamMultiCallable) def _patch_callable_name(callable_): @@ -45,7 +43,7 @@ def _patch_callable_name(callable_): gRPC callable lack the ``__name__`` attribute which causes :func:`functools.wraps` to error. This adds the attribute if needed. """ - if not hasattr(callable_, '__name__'): + if not hasattr(callable_, "__name__"): callable_.__name__ = callable_.__class__.__name__ @@ -154,11 +152,9 @@ def wrap_errors(callable_): return _wrap_unary_errors(callable_) -def create_channel(target, - credentials=None, - scopes=None, - ssl_credentials=None, - **kwargs): +def create_channel( + target, credentials=None, scopes=None, ssl_credentials=None, **kwargs +): """Create a secure channel with credentials. Args: @@ -181,13 +177,15 @@ def create_channel(target, credentials, _ = google.auth.default(scopes=scopes) else: credentials = google.auth.credentials.with_scopes_if_required( - credentials, scopes) + credentials, scopes + ) request = google.auth.transport.requests.Request() # Create the metadata plugin for inserting the authorization header. metadata_plugin = google.auth.transport.grpc.AuthMetadataPlugin( - credentials, request) + credentials, request + ) # Create a set of grpc.CallCredentials using the metadata plugin. google_auth_credentials = grpc.metadata_call_credentials(metadata_plugin) @@ -197,7 +195,8 @@ def create_channel(target, # Combine the ssl credentials and the authorization credentials. composite_credentials = grpc.composite_channel_credentials( - ssl_credentials, google_auth_credentials) + ssl_credentials, google_auth_credentials + ) if HAS_GRPC_GCP: # If grpc_gcp module is available use grpc_gcp.secure_channel, @@ -208,10 +207,10 @@ def create_channel(target, _MethodCall = collections.namedtuple( - '_MethodCall', ('request', 'timeout', 'metadata', 'credentials')) + "_MethodCall", ("request", "timeout", "metadata", "credentials") +) -_ChannelRequest = collections.namedtuple( - '_ChannelRequest', ('method', 'request')) +_ChannelRequest = collections.namedtuple("_ChannelRequest", ("method", "request")) class _CallableStub(object): @@ -238,10 +237,8 @@ def __init__(self, method, channel): request, timeout, metadata, and credentials.""" def __call__(self, request, timeout=None, metadata=None, credentials=None): - self._channel.requests.append( - _ChannelRequest(self._method, request)) - self.calls.append( - _MethodCall(request, timeout, metadata, credentials)) + self._channel.requests.append(_ChannelRequest(self._method, request)) + self.calls.append(_MethodCall(request, timeout, metadata, credentials)) self.requests.append(request) response = self.response @@ -250,8 +247,9 @@ def __call__(self, request, timeout=None, metadata=None, credentials=None): response = next(self.responses) else: raise ValueError( - '{method}.response and {method}.responses are mutually ' - 'exclusive.'.format(method=self._method)) + "{method}.response and {method}.responses are mutually " + "exclusive.".format(method=self._method) + ) if callable(response): return response(request) @@ -262,8 +260,7 @@ def __call__(self, request, timeout=None, metadata=None, credentials=None): if response is not None: return response - raise ValueError( - 'Method stub for "{}" has no response.'.format(self._method)) + raise ValueError('Method stub for "{}" has no response.'.format(self._method)) def _simplify_method_name(method): @@ -279,7 +276,7 @@ def _simplify_method_name(method): Returns: str: The simplified name of the method. """ - return method.rsplit('/', 1).pop() + return method.rsplit("/", 1).pop() class ChannelStub(grpc.Channel): @@ -356,27 +353,21 @@ def __getattr__(self, key): except KeyError: raise AttributeError - def unary_unary( - self, method, - request_serializer=None, response_deserializer=None): + def unary_unary(self, method, request_serializer=None, response_deserializer=None): """grpc.Channel.unary_unary implementation.""" return self._stub_for_method(method) - def unary_stream( - self, method, - request_serializer=None, response_deserializer=None): + def unary_stream(self, method, request_serializer=None, response_deserializer=None): """grpc.Channel.unary_stream implementation.""" return self._stub_for_method(method) - def stream_unary( - self, method, - request_serializer=None, response_deserializer=None): + def stream_unary(self, method, request_serializer=None, response_deserializer=None): """grpc.Channel.stream_unary implementation.""" return self._stub_for_method(method) def stream_stream( - self, method, - request_serializer=None, response_deserializer=None): + self, method, request_serializer=None, response_deserializer=None + ): """grpc.Channel.stream_stream implementation.""" return self._stub_for_method(method) diff --git a/api_core/google/api_core/operation.py b/api_core/google/api_core/operation.py index a97a137398a3..4147c7b267c1 100644 --- a/api_core/google/api_core/operation.py +++ b/api_core/google/api_core/operation.py @@ -68,8 +68,14 @@ class Operation(polling.PollingFuture): """ def __init__( - self, operation, refresh, cancel, - result_type, metadata_type=None, retry=polling.DEFAULT_RETRY): + self, + operation, + refresh, + cancel, + result_type, + metadata_type=None, + retry=polling.DEFAULT_RETRY, + ): super(Operation, self).__init__(retry=retry) self._operation = operation self._refresh = refresh @@ -88,11 +94,12 @@ def operation(self): @property def metadata(self): """google.protobuf.Message: the current operation metadata.""" - if not self._operation.HasField('metadata'): + if not self._operation.HasField("metadata"): return None return protobuf_helpers.from_any_pb( - self._metadata_type, self._operation.metadata) + self._metadata_type, self._operation.metadata + ) def _set_result_from_operation(self): """Set the result or exception from the operation if it is complete.""" @@ -107,20 +114,23 @@ def _set_result_from_operation(self): if not self._operation.done or self._result_set: return - if self._operation.HasField('response'): + if self._operation.HasField("response"): response = protobuf_helpers.from_any_pb( - self._result_type, self._operation.response) + self._result_type, self._operation.response + ) self.set_result(response) - elif self._operation.HasField('error'): + elif self._operation.HasField("error"): exception = exceptions.GoogleAPICallError( self._operation.error.message, errors=(self._operation.error,), - response=self._operation) + response=self._operation, + ) self.set_exception(exception) else: exception = exceptions.GoogleAPICallError( - 'Unexpected state: Long-running operation had neither ' - 'response nor error set.') + "Unexpected state: Long-running operation had neither " + "response nor error set." + ) self.set_exception(exception) def _refresh_and_update(self): @@ -156,8 +166,10 @@ def cancel(self): def cancelled(self): """True if the operation was cancelled.""" self._refresh_and_update() - return (self._operation.HasField('error') and - self._operation.error.code == code_pb2.CANCELLED) + return ( + self._operation.HasField("error") + and self._operation.error.code == code_pb2.CANCELLED + ) def _refresh_http(api_request, operation_name): @@ -172,10 +184,9 @@ def _refresh_http(api_request, operation_name): Returns: google.longrunning.operations_pb2.Operation: The operation. """ - path = 'operations/{}'.format(operation_name) - api_response = api_request(method='GET', path=path) - return json_format.ParseDict( - api_response, operations_pb2.Operation()) + path = "operations/{}".format(operation_name) + api_response = api_request(method="GET", path=path) + return json_format.ParseDict(api_response, operations_pb2.Operation()) def _cancel_http(api_request, operation_name): @@ -187,8 +198,8 @@ def _cancel_http(api_request, operation_name): :meth:`google.cloud._http.Connection.api_request`. operation_name (str): The name of the operation. """ - path = 'operations/{}:cancel'.format(operation_name) - api_request(method='POST', path=path) + path = "operations/{}:cancel".format(operation_name) + api_request(method="POST", path=path) def from_http_json(operation, api_request, result_type, **kwargs): @@ -212,12 +223,9 @@ def from_http_json(operation, api_request, result_type, **kwargs): ~.api_core.operation.Operation: The operation future to track the given operation. """ - operation_proto = json_format.ParseDict( - operation, operations_pb2.Operation()) - refresh = functools.partial( - _refresh_http, api_request, operation_proto.name) - cancel = functools.partial( - _cancel_http, api_request, operation_proto.name) + operation_proto = json_format.ParseDict(operation, operations_pb2.Operation()) + refresh = functools.partial(_refresh_http, api_request, operation_proto.name) + cancel = functools.partial(_cancel_http, api_request, operation_proto.name) return Operation(operation_proto, refresh, cancel, result_type, **kwargs) @@ -269,10 +277,8 @@ def from_grpc(operation, operations_stub, result_type, **kwargs): ~.api_core.operation.Operation: The operation future to track the given operation. """ - refresh = functools.partial( - _refresh_grpc, operations_stub, operation.name) - cancel = functools.partial( - _cancel_grpc, operations_stub, operation.name) + refresh = functools.partial(_refresh_grpc, operations_stub, operation.name) + cancel = functools.partial(_cancel_grpc, operations_stub, operation.name) return Operation(operation, refresh, cancel, result_type, **kwargs) @@ -297,8 +303,6 @@ def from_gapic(operation, operations_client, result_type, **kwargs): ~.api_core.operation.Operation: The operation future to track the given operation. """ - refresh = functools.partial( - operations_client.get_operation, operation.name) - cancel = functools.partial( - operations_client.cancel_operation, operation.name) + refresh = functools.partial(operations_client.get_operation, operation.name) + cancel = functools.partial(operations_client.cancel_operation, operation.name) return Operation(operation, refresh, cancel, result_type, **kwargs) diff --git a/api_core/google/api_core/operations_v1/__init__.py b/api_core/google/api_core/operations_v1/__init__.py index 10478d122a24..f0549561b6ff 100644 --- a/api_core/google/api_core/operations_v1/__init__.py +++ b/api_core/google/api_core/operations_v1/__init__.py @@ -16,6 +16,4 @@ from google.api_core.operations_v1.operations_client import OperationsClient -__all__ = [ - 'OperationsClient' -] +__all__ = ["OperationsClient"] diff --git a/api_core/google/api_core/operations_v1/operations_client.py b/api_core/google/api_core/operations_v1/operations_client.py index 3af699639137..cd2923bb9d09 100644 --- a/api_core/google/api_core/operations_v1/operations_client.py +++ b/api_core/google/api_core/operations_v1/operations_client.py @@ -61,34 +61,38 @@ def __init__(self, channel, client_config=operations_client_config.config): # Create all wrapped methods using the interface configuration. # The interface config contains all of the default settings for retry # and timeout for each RPC method. - interfaces = client_config['interfaces'] - interface_config = interfaces['google.longrunning.Operations'] + interfaces = client_config["interfaces"] + interface_config = interfaces["google.longrunning.Operations"] method_configs = gapic_v1.config.parse_method_configs(interface_config) self._get_operation = gapic_v1.method.wrap_method( self.operations_stub.GetOperation, - default_retry=method_configs['GetOperation'].retry, - default_timeout=method_configs['GetOperation'].timeout) + default_retry=method_configs["GetOperation"].retry, + default_timeout=method_configs["GetOperation"].timeout, + ) self._list_operations = gapic_v1.method.wrap_method( self.operations_stub.ListOperations, - default_retry=method_configs['ListOperations'].retry, - default_timeout=method_configs['ListOperations'].timeout) + default_retry=method_configs["ListOperations"].retry, + default_timeout=method_configs["ListOperations"].timeout, + ) self._cancel_operation = gapic_v1.method.wrap_method( self.operations_stub.CancelOperation, - default_retry=method_configs['CancelOperation'].retry, - default_timeout=method_configs['CancelOperation'].timeout) + default_retry=method_configs["CancelOperation"].retry, + default_timeout=method_configs["CancelOperation"].timeout, + ) self._delete_operation = gapic_v1.method.wrap_method( self.operations_stub.DeleteOperation, - default_retry=method_configs['DeleteOperation'].retry, - default_timeout=method_configs['DeleteOperation'].timeout) + default_retry=method_configs["DeleteOperation"].retry, + default_timeout=method_configs["DeleteOperation"].timeout, + ) # Service calls def get_operation( - self, name, - retry=gapic_v1.method.DEFAULT, timeout=gapic_v1.method.DEFAULT): + self, name, retry=gapic_v1.method.DEFAULT, timeout=gapic_v1.method.DEFAULT + ): """Gets the latest state of a long-running operation. Clients can use this method to poll the operation result at intervals @@ -127,8 +131,12 @@ def get_operation( return self._get_operation(request, retry=retry, timeout=timeout) def list_operations( - self, name, filter_, - retry=gapic_v1.method.DEFAULT, timeout=gapic_v1.method.DEFAULT): + self, + name, + filter_, + retry=gapic_v1.method.DEFAULT, + timeout=gapic_v1.method.DEFAULT, + ): """ Lists operations that match the specified filter in the request. @@ -177,26 +185,25 @@ def list_operations( subclass will be raised. """ # Create the request object. - request = operations_pb2.ListOperationsRequest( - name=name, filter=filter_) + request = operations_pb2.ListOperationsRequest(name=name, filter=filter_) # Create the method used to fetch pages - method = functools.partial( - self._list_operations, retry=retry, timeout=timeout) + method = functools.partial(self._list_operations, retry=retry, timeout=timeout) iterator = page_iterator.GRPCIterator( client=None, method=method, request=request, - items_field='operations', - request_token_field='page_token', - response_token_field='next_page_token') + items_field="operations", + request_token_field="page_token", + response_token_field="next_page_token", + ) return iterator def cancel_operation( - self, name, - retry=gapic_v1.method.DEFAULT, timeout=gapic_v1.method.DEFAULT): + self, name, retry=gapic_v1.method.DEFAULT, timeout=gapic_v1.method.DEFAULT + ): """Starts asynchronous cancellation on a long-running operation. The server makes a best effort to cancel the operation, but success is @@ -241,8 +248,8 @@ def cancel_operation( self._cancel_operation(request, retry=retry, timeout=timeout) def delete_operation( - self, name, - retry=gapic_v1.method.DEFAULT, timeout=gapic_v1.method.DEFAULT): + self, name, retry=gapic_v1.method.DEFAULT, timeout=gapic_v1.method.DEFAULT + ): """Deletes a long-running operation. This method indicates that the client is no longer interested in the diff --git a/api_core/google/api_core/operations_v1/operations_client_config.py b/api_core/google/api_core/operations_v1/operations_client_config.py index a3849eeb8aa7..6cf95753f4be 100644 --- a/api_core/google/api_core/operations_v1/operations_client_config.py +++ b/api_core/google/api_core/operations_v1/operations_client_config.py @@ -18,11 +18,8 @@ "interfaces": { "google.longrunning.Operations": { "retry_codes": { - "idempotent": [ - "DEADLINE_EXCEEDED", - "UNAVAILABLE" - ], - "non_idempotent": [] + "idempotent": ["DEADLINE_EXCEEDED", "UNAVAILABLE"], + "non_idempotent": [], }, "retry_params": { "default": { @@ -32,31 +29,31 @@ "initial_rpc_timeout_millis": 20000, "rpc_timeout_multiplier": 1.0, "max_rpc_timeout_millis": 600000, - "total_timeout_millis": 600000 + "total_timeout_millis": 600000, } }, "methods": { "GetOperation": { "timeout_millis": 60000, "retry_codes_name": "idempotent", - "retry_params_name": "default" + "retry_params_name": "default", }, "ListOperations": { "timeout_millis": 60000, "retry_codes_name": "idempotent", - "retry_params_name": "default" + "retry_params_name": "default", }, "CancelOperation": { "timeout_millis": 60000, "retry_codes_name": "idempotent", - "retry_params_name": "default" + "retry_params_name": "default", }, "DeleteOperation": { "timeout_millis": 60000, "retry_codes_name": "idempotent", - "retry_params_name": "default" - } - } + "retry_params_name": "default", + }, + }, } } } diff --git a/api_core/google/api_core/page_iterator.py b/api_core/google/api_core/page_iterator.py index 0cf03a619358..3ac5904399b0 100644 --- a/api_core/google/api_core/page_iterator.py +++ b/api_core/google/api_core/page_iterator.py @@ -154,8 +154,13 @@ class Iterator(object): max_results (int): The maximum number of results to fetch. """ - def __init__(self, client, item_to_value=_item_to_value_identity, - page_token=None, max_results=None): + def __init__( + self, + client, + item_to_value=_item_to_value_identity, + page_token=None, + max_results=None, + ): self._started = False self.client = client """Optional[Any]: The client that created this iterator.""" @@ -190,7 +195,7 @@ def pages(self): ValueError: If the iterator has already been started. """ if self._started: - raise ValueError('Iterator has already started', self) + raise ValueError("Iterator has already started", self) self._started = True return self._page_iter(increment=True) @@ -211,7 +216,7 @@ def __iter__(self): ValueError: If the iterator has already been started. """ if self._started: - raise ValueError('Iterator has already started', self) + raise ValueError("Iterator has already started", self) self._started = True return self._items_iter() @@ -301,20 +306,29 @@ class HTTPIterator(Iterator): .. autoattribute:: pages """ - _DEFAULT_ITEMS_KEY = 'items' - _PAGE_TOKEN = 'pageToken' - _MAX_RESULTS = 'maxResults' - _NEXT_TOKEN = 'nextPageToken' + _DEFAULT_ITEMS_KEY = "items" + _PAGE_TOKEN = "pageToken" + _MAX_RESULTS = "maxResults" + _NEXT_TOKEN = "nextPageToken" _RESERVED_PARAMS = frozenset([_PAGE_TOKEN]) - _HTTP_METHOD = 'GET' + _HTTP_METHOD = "GET" - def __init__(self, client, api_request, path, item_to_value, - items_key=_DEFAULT_ITEMS_KEY, - page_token=None, max_results=None, extra_params=None, - page_start=_do_nothing_page_start, next_token=_NEXT_TOKEN): + def __init__( + self, + client, + api_request, + path, + item_to_value, + items_key=_DEFAULT_ITEMS_KEY, + page_token=None, + max_results=None, + extra_params=None, + page_start=_do_nothing_page_start, + next_token=_NEXT_TOKEN, + ): super(HTTPIterator, self).__init__( - client, item_to_value, page_token=page_token, - max_results=max_results) + client, item_to_value, page_token=page_token, max_results=max_results + ) self.api_request = api_request self.path = path self._items_key = items_key @@ -332,11 +346,9 @@ def _verify_params(self): Raises: ValueError: If a reserved parameter is used. """ - reserved_in_use = self._RESERVED_PARAMS.intersection( - self.extra_params) + reserved_in_use = self._RESERVED_PARAMS.intersection(self.extra_params) if reserved_in_use: - raise ValueError('Using a reserved parameter', - reserved_in_use) + raise ValueError("Using a reserved parameter", reserved_in_use) def _next_page(self): """Get the next page in the iterator. @@ -394,18 +406,16 @@ def _get_next_page_response(self): ValueError: If the HTTP method is not ``GET`` or ``POST``. """ params = self._get_query_params() - if self._HTTP_METHOD == 'GET': + if self._HTTP_METHOD == "GET": return self.api_request( - method=self._HTTP_METHOD, - path=self.path, - query_params=params) - elif self._HTTP_METHOD == 'POST': + method=self._HTTP_METHOD, path=self.path, query_params=params + ) + elif self._HTTP_METHOD == "POST": return self.api_request( - method=self._HTTP_METHOD, - path=self.path, - data=params) + method=self._HTTP_METHOD, path=self.path, data=params + ) else: - raise ValueError('Unexpected HTTP method', self._HTTP_METHOD) + raise ValueError("Unexpected HTTP method", self._HTTP_METHOD) class _GAXIterator(Iterator): @@ -425,8 +435,11 @@ class _GAXIterator(Iterator): def __init__(self, client, page_iter, item_to_value, max_results=None): super(_GAXIterator, self).__init__( - client, item_to_value, page_token=page_iter.page_token, - max_results=max_results) + client, + item_to_value, + page_token=page_iter.page_token, + max_results=max_results, + ) self._gax_page_iter = page_iter def _next_page(self): @@ -474,21 +487,23 @@ class GRPCIterator(Iterator): .. autoattribute:: pages """ - _DEFAULT_REQUEST_TOKEN_FIELD = 'page_token' - _DEFAULT_RESPONSE_TOKEN_FIELD = 'next_page_token' + _DEFAULT_REQUEST_TOKEN_FIELD = "page_token" + _DEFAULT_RESPONSE_TOKEN_FIELD = "next_page_token" def __init__( - self, - client, - method, - request, - items_field, - item_to_value=_item_to_value_identity, - request_token_field=_DEFAULT_REQUEST_TOKEN_FIELD, - response_token_field=_DEFAULT_RESPONSE_TOKEN_FIELD, - max_results=None): + self, + client, + method, + request, + items_field, + item_to_value=_item_to_value_identity, + request_token_field=_DEFAULT_REQUEST_TOKEN_FIELD, + response_token_field=_DEFAULT_RESPONSE_TOKEN_FIELD, + max_results=None, + ): super(GRPCIterator, self).__init__( - client, item_to_value, max_results=max_results) + client, item_to_value, max_results=max_results + ) self._method = method self._request = request self._items_field = items_field @@ -506,8 +521,7 @@ def _next_page(self): return None if self.next_page_token is not None: - setattr( - self._request, self._request_token_field, self.next_page_token) + setattr(self._request, self._request_token_field, self.next_page_token) response = self._method(self._request) diff --git a/api_core/google/api_core/path_template.py b/api_core/google/api_core/path_template.py index 5d6609eac829..bb549356d284 100644 --- a/api_core/google/api_core/path_template.py +++ b/api_core/google/api_core/path_template.py @@ -41,7 +41,8 @@ # - "{name=**}": a multi-segment wildcard named variable, for example # "shelf/{name=**}" # - "{name=/path/*/**}": a multi-segment named variable with a sub-template. -_VARIABLE_RE = re.compile(r""" +_VARIABLE_RE = re.compile( + r""" ( # Capture the entire variable expression (?P\*\*?) # Match & capture * and ** positional variables. | @@ -52,11 +53,13 @@ (?:=(?P