diff --git a/google/pubsub_v1/services/publisher/async_client.py b/google/pubsub_v1/services/publisher/async_client.py index 4fd755d91..7079025e9 100644 --- a/google/pubsub_v1/services/publisher/async_client.py +++ b/google/pubsub_v1/services/publisher/async_client.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import logging as std_logging from collections import OrderedDict import re from typing import ( @@ -54,6 +55,15 @@ from .transports.grpc_asyncio import PublisherGrpcAsyncIOTransport from .client import PublisherClient +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + class PublisherAsyncClient: """The service that an application uses to manipulate topics, @@ -259,6 +269,28 @@ def __init__( client_info=client_info, ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.pubsub_v1.PublisherAsyncClient`.", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "universeDomain": getattr( + self._client._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._client._transport._credentials).__module__}.{type(self._client._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._client._transport, "_credentials") + else { + "serviceName": "google.pubsub.v1.Publisher", + "credentialsType": None, + }, + ) + async def create_topic( self, request: Optional[Union[pubsub.Topic, dict]] = None, @@ -266,7 +298,7 @@ async def create_topic( name: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Topic: r"""Creates the given topic with the given name. See the [resource name rules] @@ -318,8 +350,10 @@ async def sample_create_topic(): should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Topic: @@ -379,7 +413,7 @@ async def update_topic( update_mask: Optional[field_mask_pb2.FieldMask] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Topic: r"""Updates an existing topic by updating the fields specified in the update mask. Note that certain @@ -438,8 +472,10 @@ async def sample_update_topic(): should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Topic: @@ -503,7 +539,7 @@ async def publish( messages: Optional[MutableSequence[pubsub.PubsubMessage]] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.PublishResponse: r"""Adds one or more messages to the topic. Returns ``NOT_FOUND`` if the topic does not exist. @@ -554,8 +590,10 @@ async def sample_publish(): should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.PublishResponse: @@ -614,7 +652,7 @@ async def get_topic( topic: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Topic: r"""Gets the configuration of a topic. @@ -658,8 +696,10 @@ async def sample_get_topic(): should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Topic: @@ -718,7 +758,7 @@ async def list_topics( project: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListTopicsAsyncPager: r"""Lists matching topics. @@ -763,8 +803,10 @@ async def sample_list_topics(): should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.services.publisher.pagers.ListTopicsAsyncPager: @@ -838,7 +880,7 @@ async def list_topic_subscriptions( topic: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListTopicSubscriptionsAsyncPager: r"""Lists the names of the attached subscriptions on this topic. @@ -885,8 +927,10 @@ async def sample_list_topic_subscriptions(): should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.services.publisher.pagers.ListTopicSubscriptionsAsyncPager: @@ -960,7 +1004,7 @@ async def list_topic_snapshots( topic: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListTopicSnapshotsAsyncPager: r"""Lists the names of the snapshots on this topic. Snapshots are used in @@ -1011,8 +1055,10 @@ async def sample_list_topic_snapshots(): should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.services.publisher.pagers.ListTopicSnapshotsAsyncPager: @@ -1086,7 +1132,7 @@ async def delete_topic( topic: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> None: r"""Deletes the topic with the given name. Returns ``NOT_FOUND`` if the topic does not exist. After a topic is deleted, a new topic @@ -1132,8 +1178,10 @@ async def sample_delete_topic(): should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have @@ -1184,7 +1232,7 @@ async def detach_subscription( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.DetachSubscriptionResponse: r"""Detaches a subscription from this topic. All messages retained in the subscription are dropped. Subsequent ``Pull`` and @@ -1226,8 +1274,10 @@ async def sample_detach_subscription(): should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.DetachSubscriptionResponse: @@ -1275,7 +1325,7 @@ async def set_iam_policy( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> policy_pb2.Policy: r"""Sets the IAM access control policy on the specified function. @@ -1289,8 +1339,10 @@ async def set_iam_policy( should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.policy_pb2.Policy: Defines an Identity and Access Management (IAM) policy. @@ -1394,7 +1446,7 @@ async def get_iam_policy( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> policy_pb2.Policy: r"""Gets the IAM access control policy for a function. @@ -1409,8 +1461,10 @@ async def get_iam_policy( should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.policy_pb2.Policy: Defines an Identity and Access Management (IAM) policy. @@ -1515,7 +1569,7 @@ async def test_iam_permissions( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> iam_policy_pb2.TestIamPermissionsResponse: r"""Tests the specified permissions against the IAM access control policy for a function. @@ -1531,8 +1585,10 @@ async def test_iam_permissions( should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~iam_policy_pb2.PolicyTestIamPermissionsResponse: Response message for ``TestIamPermissions`` method. diff --git a/google/pubsub_v1/services/publisher/client.py b/google/pubsub_v1/services/publisher/client.py index 698aed49e..2a022cee6 100644 --- a/google/pubsub_v1/services/publisher/client.py +++ b/google/pubsub_v1/services/publisher/client.py @@ -14,6 +14,9 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging import functools import os import re @@ -50,6 +53,15 @@ except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore from google.protobuf import duration_pb2 # type: ignore @@ -524,6 +536,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -628,6 +667,10 @@ def __init__( # Initialize the universe domain validation. self._is_universe_domain_valid = False + if CLIENT_LOGGING_SUPPORTED: # pragma: NO COVER + # Setup logging. + client_logging.initialize_logging() + api_key_value = getattr(self._client_options, "api_key", None) if api_key_value and credentials: raise ValueError( @@ -699,6 +742,29 @@ def __init__( api_audience=self._client_options.api_audience, ) + if "async" not in str(self._transport): + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.pubsub_v1.PublisherClient`.", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "universeDomain": getattr( + self._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._transport._credentials).__module__}.{type(self._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._transport, "_credentials") + else { + "serviceName": "google.pubsub.v1.Publisher", + "credentialsType": None, + }, + ) + def create_topic( self, request: Optional[Union[pubsub.Topic, dict]] = None, @@ -706,7 +772,7 @@ def create_topic( name: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Topic: r"""Creates the given topic with the given name. See the [resource name rules] @@ -758,8 +824,10 @@ def sample_create_topic(): should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Topic: @@ -816,7 +884,7 @@ def update_topic( update_mask: Optional[field_mask_pb2.FieldMask] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Topic: r"""Updates an existing topic by updating the fields specified in the update mask. Note that certain @@ -875,8 +943,10 @@ def sample_update_topic(): should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Topic: @@ -937,7 +1007,7 @@ def publish( messages: Optional[MutableSequence[pubsub.PubsubMessage]] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.PublishResponse: r"""Adds one or more messages to the topic. Returns ``NOT_FOUND`` if the topic does not exist. @@ -988,8 +1058,10 @@ def sample_publish(): should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.PublishResponse: @@ -1047,7 +1119,7 @@ def get_topic( topic: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Topic: r"""Gets the configuration of a topic. @@ -1091,8 +1163,10 @@ def sample_get_topic(): should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Topic: @@ -1148,7 +1222,7 @@ def list_topics( project: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListTopicsPager: r"""Lists matching topics. @@ -1193,8 +1267,10 @@ def sample_list_topics(): should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.services.publisher.pagers.ListTopicsPager: @@ -1265,7 +1341,7 @@ def list_topic_subscriptions( topic: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListTopicSubscriptionsPager: r"""Lists the names of the attached subscriptions on this topic. @@ -1312,8 +1388,10 @@ def sample_list_topic_subscriptions(): should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.services.publisher.pagers.ListTopicSubscriptionsPager: @@ -1384,7 +1462,7 @@ def list_topic_snapshots( topic: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListTopicSnapshotsPager: r"""Lists the names of the snapshots on this topic. Snapshots are used in @@ -1435,8 +1513,10 @@ def sample_list_topic_snapshots(): should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.services.publisher.pagers.ListTopicSnapshotsPager: @@ -1507,7 +1587,7 @@ def delete_topic( topic: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> None: r"""Deletes the topic with the given name. Returns ``NOT_FOUND`` if the topic does not exist. After a topic is deleted, a new topic @@ -1553,8 +1633,10 @@ def sample_delete_topic(): should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have @@ -1602,7 +1684,7 @@ def detach_subscription( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.DetachSubscriptionResponse: r"""Detaches a subscription from this topic. All messages retained in the subscription are dropped. Subsequent ``Pull`` and @@ -1644,8 +1726,10 @@ def sample_detach_subscription(): should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.DetachSubscriptionResponse: @@ -1704,7 +1788,7 @@ def set_iam_policy( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> policy_pb2.Policy: r"""Sets the IAM access control policy on the specified function. @@ -1718,8 +1802,10 @@ def set_iam_policy( should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.policy_pb2.Policy: Defines an Identity and Access Management (IAM) policy. @@ -1811,16 +1897,20 @@ def set_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_iam_policy( self, @@ -1828,7 +1918,7 @@ def get_iam_policy( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> policy_pb2.Policy: r"""Gets the IAM access control policy for a function. @@ -1843,8 +1933,10 @@ def get_iam_policy( any, should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.policy_pb2.Policy: Defines an Identity and Access Management (IAM) policy. @@ -1936,16 +2028,20 @@ def get_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def test_iam_permissions( self, @@ -1953,7 +2049,7 @@ def test_iam_permissions( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: TimeoutType = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> iam_policy_pb2.TestIamPermissionsResponse: r"""Tests the specified IAM permissions against the IAM access control policy for a function. @@ -1969,8 +2065,10 @@ def test_iam_permissions( if any, should be retried. timeout (TimeoutType): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.iam_policy_pb2.TestIamPermissionsResponse: Response message for ``TestIamPermissions`` method. @@ -1999,16 +2097,20 @@ def test_iam_permissions( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/google/pubsub_v1/services/publisher/pagers.py b/google/pubsub_v1/services/publisher/pagers.py index de3490c39..da6de8dfa 100644 --- a/google/pubsub_v1/services/publisher/pagers.py +++ b/google/pubsub_v1/services/publisher/pagers.py @@ -66,7 +66,7 @@ def __init__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = () + metadata: Sequence[Tuple[str, Union[str, bytes]]] = () ): """Instantiate the pager. @@ -80,8 +80,10 @@ def __init__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ self._method = method self._request = pubsub.ListTopicsRequest(request) @@ -140,7 +142,7 @@ def __init__( *, retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = () + metadata: Sequence[Tuple[str, Union[str, bytes]]] = () ): """Instantiates the pager. @@ -154,8 +156,10 @@ def __init__( retry (google.api_core.retry.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ self._method = method self._request = pubsub.ListTopicsRequest(request) @@ -218,7 +222,7 @@ def __init__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = () + metadata: Sequence[Tuple[str, Union[str, bytes]]] = () ): """Instantiate the pager. @@ -232,8 +236,10 @@ def __init__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ self._method = method self._request = pubsub.ListTopicSubscriptionsRequest(request) @@ -292,7 +298,7 @@ def __init__( *, retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = () + metadata: Sequence[Tuple[str, Union[str, bytes]]] = () ): """Instantiates the pager. @@ -306,8 +312,10 @@ def __init__( retry (google.api_core.retry.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ self._method = method self._request = pubsub.ListTopicSubscriptionsRequest(request) @@ -370,7 +378,7 @@ def __init__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = () + metadata: Sequence[Tuple[str, Union[str, bytes]]] = () ): """Instantiate the pager. @@ -384,8 +392,10 @@ def __init__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ self._method = method self._request = pubsub.ListTopicSnapshotsRequest(request) @@ -444,7 +454,7 @@ def __init__( *, retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = () + metadata: Sequence[Tuple[str, Union[str, bytes]]] = () ): """Instantiates the pager. @@ -458,8 +468,10 @@ def __init__( retry (google.api_core.retry.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ self._method = method self._request = pubsub.ListTopicSnapshotsRequest(request) diff --git a/google/pubsub_v1/services/publisher/transports/grpc.py b/google/pubsub_v1/services/publisher/transports/grpc.py index b6e07b21e..b4fac4bc3 100644 --- a/google/pubsub_v1/services/publisher/transports/grpc.py +++ b/google/pubsub_v1/services/publisher/transports/grpc.py @@ -13,6 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import json +import logging as std_logging +import pickle import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union @@ -21,8 +24,11 @@ import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore +import proto # type: ignore from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore @@ -30,6 +36,81 @@ from google.pubsub_v1.types import pubsub from .base import PublisherTransport, DEFAULT_CLIENT_INFO +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor(grpc.UnaryUnaryClientInterceptor): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": client_call_details.method, + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + + response = continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = response.result() + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response for {client_call_details.method}.", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class PublisherGrpcTransport(PublisherTransport): """gRPC backend transport for Publisher. @@ -186,7 +267,12 @@ def __init__( ], ) - # Wrap messages. This must be done after self._grpc_channel exists + self._interceptor = _LoggingClientInterceptor() + self._logged_channel = grpc.intercept_channel( + self._grpc_channel, self._interceptor + ) + + # Wrap messages. This must be done after self._logged_channel exists self._prep_wrapped_messages(client_info) @classmethod @@ -260,7 +346,7 @@ def create_topic(self) -> Callable[[pubsub.Topic], pubsub.Topic]: # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_topic" not in self._stubs: - self._stubs["create_topic"] = self.grpc_channel.unary_unary( + self._stubs["create_topic"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Publisher/CreateTopic", request_serializer=pubsub.Topic.serialize, response_deserializer=pubsub.Topic.deserialize, @@ -286,7 +372,7 @@ def update_topic(self) -> Callable[[pubsub.UpdateTopicRequest], pubsub.Topic]: # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_topic" not in self._stubs: - self._stubs["update_topic"] = self.grpc_channel.unary_unary( + self._stubs["update_topic"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Publisher/UpdateTopic", request_serializer=pubsub.UpdateTopicRequest.serialize, response_deserializer=pubsub.Topic.deserialize, @@ -311,7 +397,7 @@ def publish(self) -> Callable[[pubsub.PublishRequest], pubsub.PublishResponse]: # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "publish" not in self._stubs: - self._stubs["publish"] = self.grpc_channel.unary_unary( + self._stubs["publish"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Publisher/Publish", request_serializer=pubsub.PublishRequest.serialize, response_deserializer=pubsub.PublishResponse.deserialize, @@ -335,7 +421,7 @@ def get_topic(self) -> Callable[[pubsub.GetTopicRequest], pubsub.Topic]: # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_topic" not in self._stubs: - self._stubs["get_topic"] = self.grpc_channel.unary_unary( + self._stubs["get_topic"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Publisher/GetTopic", request_serializer=pubsub.GetTopicRequest.serialize, response_deserializer=pubsub.Topic.deserialize, @@ -361,7 +447,7 @@ def list_topics( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_topics" not in self._stubs: - self._stubs["list_topics"] = self.grpc_channel.unary_unary( + self._stubs["list_topics"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Publisher/ListTopics", request_serializer=pubsub.ListTopicsRequest.serialize, response_deserializer=pubsub.ListTopicsResponse.deserialize, @@ -390,7 +476,7 @@ def list_topic_subscriptions( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_topic_subscriptions" not in self._stubs: - self._stubs["list_topic_subscriptions"] = self.grpc_channel.unary_unary( + self._stubs["list_topic_subscriptions"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Publisher/ListTopicSubscriptions", request_serializer=pubsub.ListTopicSubscriptionsRequest.serialize, response_deserializer=pubsub.ListTopicSubscriptionsResponse.deserialize, @@ -423,7 +509,7 @@ def list_topic_snapshots( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_topic_snapshots" not in self._stubs: - self._stubs["list_topic_snapshots"] = self.grpc_channel.unary_unary( + self._stubs["list_topic_snapshots"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Publisher/ListTopicSnapshots", request_serializer=pubsub.ListTopicSnapshotsRequest.serialize, response_deserializer=pubsub.ListTopicSnapshotsResponse.deserialize, @@ -452,7 +538,7 @@ def delete_topic(self) -> Callable[[pubsub.DeleteTopicRequest], empty_pb2.Empty] # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_topic" not in self._stubs: - self._stubs["delete_topic"] = self.grpc_channel.unary_unary( + self._stubs["delete_topic"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Publisher/DeleteTopic", request_serializer=pubsub.DeleteTopicRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -484,7 +570,7 @@ def detach_subscription( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "detach_subscription" not in self._stubs: - self._stubs["detach_subscription"] = self.grpc_channel.unary_unary( + self._stubs["detach_subscription"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Publisher/DetachSubscription", request_serializer=pubsub.DetachSubscriptionRequest.serialize, response_deserializer=pubsub.DetachSubscriptionResponse.deserialize, @@ -509,7 +595,7 @@ def set_iam_policy( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "set_iam_policy" not in self._stubs: - self._stubs["set_iam_policy"] = self.grpc_channel.unary_unary( + self._stubs["set_iam_policy"] = self._logged_channel.unary_unary( "/google.iam.v1.IAMPolicy/SetIamPolicy", request_serializer=iam_policy_pb2.SetIamPolicyRequest.SerializeToString, response_deserializer=policy_pb2.Policy.FromString, @@ -535,7 +621,7 @@ def get_iam_policy( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_iam_policy" not in self._stubs: - self._stubs["get_iam_policy"] = self.grpc_channel.unary_unary( + self._stubs["get_iam_policy"] = self._logged_channel.unary_unary( "/google.iam.v1.IAMPolicy/GetIamPolicy", request_serializer=iam_policy_pb2.GetIamPolicyRequest.SerializeToString, response_deserializer=policy_pb2.Policy.FromString, @@ -564,7 +650,7 @@ def test_iam_permissions( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "test_iam_permissions" not in self._stubs: - self._stubs["test_iam_permissions"] = self.grpc_channel.unary_unary( + self._stubs["test_iam_permissions"] = self._logged_channel.unary_unary( "/google.iam.v1.IAMPolicy/TestIamPermissions", request_serializer=iam_policy_pb2.TestIamPermissionsRequest.SerializeToString, response_deserializer=iam_policy_pb2.TestIamPermissionsResponse.FromString, @@ -572,7 +658,7 @@ def test_iam_permissions( return self._stubs["test_iam_permissions"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/google/pubsub_v1/services/publisher/transports/grpc_asyncio.py b/google/pubsub_v1/services/publisher/transports/grpc_asyncio.py index 6a293137a..7c0ff0bbe 100644 --- a/google/pubsub_v1/services/publisher/transports/grpc_asyncio.py +++ b/google/pubsub_v1/services/publisher/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import pickle +import logging as std_logging import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union @@ -23,8 +26,11 @@ from google.api_core import retry_async as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore +import proto # type: ignore from grpc.experimental import aio # type: ignore from google.iam.v1 import iam_policy_pb2 # type: ignore @@ -34,6 +40,82 @@ from .base import PublisherTransport, DEFAULT_CLIENT_INFO from .grpc import PublisherGrpcTransport +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientAIOInterceptor( + grpc.aio.UnaryUnaryClientInterceptor +): # pragma: NO COVER + async def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": str(client_call_details.method), + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + response = await continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = await response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = await response + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response to rpc {client_call_details.method}.", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class PublisherGrpcAsyncIOTransport(PublisherTransport): """gRPC AsyncIO backend transport for Publisher. @@ -233,10 +315,13 @@ def __init__( ], ) - # Wrap messages. This must be done after self._grpc_channel exists + self._interceptor = _LoggingClientAIOInterceptor() + self._grpc_channel._unary_unary_interceptors.append(self._interceptor) + self._logged_channel = self._grpc_channel self._wrap_with_kind = ( "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters ) + # Wrap messages. This must be done after self._logged_channel exists self._prep_wrapped_messages(client_info) @property @@ -268,7 +353,7 @@ def create_topic(self) -> Callable[[pubsub.Topic], Awaitable[pubsub.Topic]]: # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_topic" not in self._stubs: - self._stubs["create_topic"] = self.grpc_channel.unary_unary( + self._stubs["create_topic"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Publisher/CreateTopic", request_serializer=pubsub.Topic.serialize, response_deserializer=pubsub.Topic.deserialize, @@ -296,7 +381,7 @@ def update_topic( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_topic" not in self._stubs: - self._stubs["update_topic"] = self.grpc_channel.unary_unary( + self._stubs["update_topic"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Publisher/UpdateTopic", request_serializer=pubsub.UpdateTopicRequest.serialize, response_deserializer=pubsub.Topic.deserialize, @@ -323,7 +408,7 @@ def publish( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "publish" not in self._stubs: - self._stubs["publish"] = self.grpc_channel.unary_unary( + self._stubs["publish"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Publisher/Publish", request_serializer=pubsub.PublishRequest.serialize, response_deserializer=pubsub.PublishResponse.deserialize, @@ -347,7 +432,7 @@ def get_topic(self) -> Callable[[pubsub.GetTopicRequest], Awaitable[pubsub.Topic # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_topic" not in self._stubs: - self._stubs["get_topic"] = self.grpc_channel.unary_unary( + self._stubs["get_topic"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Publisher/GetTopic", request_serializer=pubsub.GetTopicRequest.serialize, response_deserializer=pubsub.Topic.deserialize, @@ -373,7 +458,7 @@ def list_topics( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_topics" not in self._stubs: - self._stubs["list_topics"] = self.grpc_channel.unary_unary( + self._stubs["list_topics"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Publisher/ListTopics", request_serializer=pubsub.ListTopicsRequest.serialize, response_deserializer=pubsub.ListTopicsResponse.deserialize, @@ -403,7 +488,7 @@ def list_topic_subscriptions( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_topic_subscriptions" not in self._stubs: - self._stubs["list_topic_subscriptions"] = self.grpc_channel.unary_unary( + self._stubs["list_topic_subscriptions"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Publisher/ListTopicSubscriptions", request_serializer=pubsub.ListTopicSubscriptionsRequest.serialize, response_deserializer=pubsub.ListTopicSubscriptionsResponse.deserialize, @@ -436,7 +521,7 @@ def list_topic_snapshots( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_topic_snapshots" not in self._stubs: - self._stubs["list_topic_snapshots"] = self.grpc_channel.unary_unary( + self._stubs["list_topic_snapshots"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Publisher/ListTopicSnapshots", request_serializer=pubsub.ListTopicSnapshotsRequest.serialize, response_deserializer=pubsub.ListTopicSnapshotsResponse.deserialize, @@ -467,7 +552,7 @@ def delete_topic( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_topic" not in self._stubs: - self._stubs["delete_topic"] = self.grpc_channel.unary_unary( + self._stubs["delete_topic"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Publisher/DeleteTopic", request_serializer=pubsub.DeleteTopicRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -499,7 +584,7 @@ def detach_subscription( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "detach_subscription" not in self._stubs: - self._stubs["detach_subscription"] = self.grpc_channel.unary_unary( + self._stubs["detach_subscription"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Publisher/DetachSubscription", request_serializer=pubsub.DetachSubscriptionRequest.serialize, response_deserializer=pubsub.DetachSubscriptionResponse.deserialize, @@ -524,7 +609,7 @@ def set_iam_policy( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "set_iam_policy" not in self._stubs: - self._stubs["set_iam_policy"] = self.grpc_channel.unary_unary( + self._stubs["set_iam_policy"] = self._logged_channel.unary_unary( "/google.iam.v1.IAMPolicy/SetIamPolicy", request_serializer=iam_policy_pb2.SetIamPolicyRequest.SerializeToString, response_deserializer=policy_pb2.Policy.FromString, @@ -550,7 +635,7 @@ def get_iam_policy( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_iam_policy" not in self._stubs: - self._stubs["get_iam_policy"] = self.grpc_channel.unary_unary( + self._stubs["get_iam_policy"] = self._logged_channel.unary_unary( "/google.iam.v1.IAMPolicy/GetIamPolicy", request_serializer=iam_policy_pb2.GetIamPolicyRequest.SerializeToString, response_deserializer=policy_pb2.Policy.FromString, @@ -579,7 +664,7 @@ def test_iam_permissions( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "test_iam_permissions" not in self._stubs: - self._stubs["test_iam_permissions"] = self.grpc_channel.unary_unary( + self._stubs["test_iam_permissions"] = self._logged_channel.unary_unary( "/google.iam.v1.IAMPolicy/TestIamPermissions", request_serializer=iam_policy_pb2.TestIamPermissionsRequest.SerializeToString, response_deserializer=iam_policy_pb2.TestIamPermissionsResponse.FromString, @@ -752,7 +837,7 @@ def _wrap_method(self, func, *args, **kwargs): return gapic_v1.method_async.wrap_method(func, *args, **kwargs) def close(self): - return self.grpc_channel.close() + return self._logged_channel.close() @property def kind(self) -> str: diff --git a/google/pubsub_v1/services/publisher/transports/rest.py b/google/pubsub_v1/services/publisher/transports/rest.py index 3685dd55f..69e4dba9e 100644 --- a/google/pubsub_v1/services/publisher/transports/rest.py +++ b/google/pubsub_v1/services/publisher/transports/rest.py @@ -13,9 +13,10 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import logging +import json # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore -import json # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries @@ -47,6 +48,14 @@ except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = logging.getLogger(__name__) DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, @@ -145,8 +154,8 @@ def post_update_topic(self, response): """ def pre_create_topic( - self, request: pubsub.Topic, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[pubsub.Topic, Sequence[Tuple[str, str]]]: + self, request: pubsub.Topic, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[pubsub.Topic, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for create_topic Override in a subclass to manipulate the request or metadata @@ -157,15 +166,38 @@ def pre_create_topic( def post_create_topic(self, response: pubsub.Topic) -> pubsub.Topic: """Post-rpc interceptor for create_topic - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_topic_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Publisher server but before - it is returned to user code. + it is returned to user code. This `post_create_topic` interceptor runs + before the `post_create_topic_with_metadata` interceptor. """ return response + def post_create_topic_with_metadata( + self, response: pubsub.Topic, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[pubsub.Topic, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_topic + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Publisher server but before it is returned to user code. + + We recommend only using this `post_create_topic_with_metadata` + interceptor in new development instead of the `post_create_topic` interceptor. + When both interceptors are used, this `post_create_topic_with_metadata` interceptor runs after the + `post_create_topic` interceptor. The (possibly modified) response returned by + `post_create_topic` will be passed to + `post_create_topic_with_metadata`. + """ + return response, metadata + def pre_delete_topic( - self, request: pubsub.DeleteTopicRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[pubsub.DeleteTopicRequest, Sequence[Tuple[str, str]]]: + self, + request: pubsub.DeleteTopicRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.DeleteTopicRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for delete_topic Override in a subclass to manipulate the request or metadata @@ -176,8 +208,10 @@ def pre_delete_topic( def pre_detach_subscription( self, request: pubsub.DetachSubscriptionRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[pubsub.DetachSubscriptionRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + pubsub.DetachSubscriptionRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for detach_subscription Override in a subclass to manipulate the request or metadata @@ -190,15 +224,42 @@ def post_detach_subscription( ) -> pubsub.DetachSubscriptionResponse: """Post-rpc interceptor for detach_subscription - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_detach_subscription_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Publisher server but before - it is returned to user code. + it is returned to user code. This `post_detach_subscription` interceptor runs + before the `post_detach_subscription_with_metadata` interceptor. """ return response + def post_detach_subscription_with_metadata( + self, + response: pubsub.DetachSubscriptionResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + pubsub.DetachSubscriptionResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for detach_subscription + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Publisher server but before it is returned to user code. + + We recommend only using this `post_detach_subscription_with_metadata` + interceptor in new development instead of the `post_detach_subscription` interceptor. + When both interceptors are used, this `post_detach_subscription_with_metadata` interceptor runs after the + `post_detach_subscription` interceptor. The (possibly modified) response returned by + `post_detach_subscription` will be passed to + `post_detach_subscription_with_metadata`. + """ + return response, metadata + def pre_get_topic( - self, request: pubsub.GetTopicRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[pubsub.GetTopicRequest, Sequence[Tuple[str, str]]]: + self, + request: pubsub.GetTopicRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.GetTopicRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for get_topic Override in a subclass to manipulate the request or metadata @@ -209,15 +270,38 @@ def pre_get_topic( def post_get_topic(self, response: pubsub.Topic) -> pubsub.Topic: """Post-rpc interceptor for get_topic - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_topic_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Publisher server but before - it is returned to user code. + it is returned to user code. This `post_get_topic` interceptor runs + before the `post_get_topic_with_metadata` interceptor. """ return response + def post_get_topic_with_metadata( + self, response: pubsub.Topic, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[pubsub.Topic, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_topic + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Publisher server but before it is returned to user code. + + We recommend only using this `post_get_topic_with_metadata` + interceptor in new development instead of the `post_get_topic` interceptor. + When both interceptors are used, this `post_get_topic_with_metadata` interceptor runs after the + `post_get_topic` interceptor. The (possibly modified) response returned by + `post_get_topic` will be passed to + `post_get_topic_with_metadata`. + """ + return response, metadata + def pre_list_topics( - self, request: pubsub.ListTopicsRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[pubsub.ListTopicsRequest, Sequence[Tuple[str, str]]]: + self, + request: pubsub.ListTopicsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.ListTopicsRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for list_topics Override in a subclass to manipulate the request or metadata @@ -230,17 +314,42 @@ def post_list_topics( ) -> pubsub.ListTopicsResponse: """Post-rpc interceptor for list_topics - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_topics_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Publisher server but before - it is returned to user code. + it is returned to user code. This `post_list_topics` interceptor runs + before the `post_list_topics_with_metadata` interceptor. """ return response + def post_list_topics_with_metadata( + self, + response: pubsub.ListTopicsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.ListTopicsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_topics + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Publisher server but before it is returned to user code. + + We recommend only using this `post_list_topics_with_metadata` + interceptor in new development instead of the `post_list_topics` interceptor. + When both interceptors are used, this `post_list_topics_with_metadata` interceptor runs after the + `post_list_topics` interceptor. The (possibly modified) response returned by + `post_list_topics` will be passed to + `post_list_topics_with_metadata`. + """ + return response, metadata + def pre_list_topic_snapshots( self, request: pubsub.ListTopicSnapshotsRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[pubsub.ListTopicSnapshotsRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + pubsub.ListTopicSnapshotsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for list_topic_snapshots Override in a subclass to manipulate the request or metadata @@ -253,17 +362,44 @@ def post_list_topic_snapshots( ) -> pubsub.ListTopicSnapshotsResponse: """Post-rpc interceptor for list_topic_snapshots - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_topic_snapshots_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Publisher server but before - it is returned to user code. + it is returned to user code. This `post_list_topic_snapshots` interceptor runs + before the `post_list_topic_snapshots_with_metadata` interceptor. """ return response + def post_list_topic_snapshots_with_metadata( + self, + response: pubsub.ListTopicSnapshotsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + pubsub.ListTopicSnapshotsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_topic_snapshots + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Publisher server but before it is returned to user code. + + We recommend only using this `post_list_topic_snapshots_with_metadata` + interceptor in new development instead of the `post_list_topic_snapshots` interceptor. + When both interceptors are used, this `post_list_topic_snapshots_with_metadata` interceptor runs after the + `post_list_topic_snapshots` interceptor. The (possibly modified) response returned by + `post_list_topic_snapshots` will be passed to + `post_list_topic_snapshots_with_metadata`. + """ + return response, metadata + def pre_list_topic_subscriptions( self, request: pubsub.ListTopicSubscriptionsRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[pubsub.ListTopicSubscriptionsRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + pubsub.ListTopicSubscriptionsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for list_topic_subscriptions Override in a subclass to manipulate the request or metadata @@ -276,15 +412,42 @@ def post_list_topic_subscriptions( ) -> pubsub.ListTopicSubscriptionsResponse: """Post-rpc interceptor for list_topic_subscriptions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_topic_subscriptions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Publisher server but before - it is returned to user code. + it is returned to user code. This `post_list_topic_subscriptions` interceptor runs + before the `post_list_topic_subscriptions_with_metadata` interceptor. """ return response + def post_list_topic_subscriptions_with_metadata( + self, + response: pubsub.ListTopicSubscriptionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + pubsub.ListTopicSubscriptionsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_topic_subscriptions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Publisher server but before it is returned to user code. + + We recommend only using this `post_list_topic_subscriptions_with_metadata` + interceptor in new development instead of the `post_list_topic_subscriptions` interceptor. + When both interceptors are used, this `post_list_topic_subscriptions_with_metadata` interceptor runs after the + `post_list_topic_subscriptions` interceptor. The (possibly modified) response returned by + `post_list_topic_subscriptions` will be passed to + `post_list_topic_subscriptions_with_metadata`. + """ + return response, metadata + def pre_publish( - self, request: pubsub.PublishRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[pubsub.PublishRequest, Sequence[Tuple[str, str]]]: + self, + request: pubsub.PublishRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.PublishRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for publish Override in a subclass to manipulate the request or metadata @@ -295,15 +458,40 @@ def pre_publish( def post_publish(self, response: pubsub.PublishResponse) -> pubsub.PublishResponse: """Post-rpc interceptor for publish - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_publish_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Publisher server but before - it is returned to user code. + it is returned to user code. This `post_publish` interceptor runs + before the `post_publish_with_metadata` interceptor. """ return response + def post_publish_with_metadata( + self, + response: pubsub.PublishResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.PublishResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for publish + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Publisher server but before it is returned to user code. + + We recommend only using this `post_publish_with_metadata` + interceptor in new development instead of the `post_publish` interceptor. + When both interceptors are used, this `post_publish_with_metadata` interceptor runs after the + `post_publish` interceptor. The (possibly modified) response returned by + `post_publish` will be passed to + `post_publish_with_metadata`. + """ + return response, metadata + def pre_update_topic( - self, request: pubsub.UpdateTopicRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[pubsub.UpdateTopicRequest, Sequence[Tuple[str, str]]]: + self, + request: pubsub.UpdateTopicRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.UpdateTopicRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for update_topic Override in a subclass to manipulate the request or metadata @@ -314,17 +502,40 @@ def pre_update_topic( def post_update_topic(self, response: pubsub.Topic) -> pubsub.Topic: """Post-rpc interceptor for update_topic - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_topic_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Publisher server but before - it is returned to user code. + it is returned to user code. This `post_update_topic` interceptor runs + before the `post_update_topic_with_metadata` interceptor. """ return response + def post_update_topic_with_metadata( + self, response: pubsub.Topic, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[pubsub.Topic, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_topic + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Publisher server but before it is returned to user code. + + We recommend only using this `post_update_topic_with_metadata` + interceptor in new development instead of the `post_update_topic` interceptor. + When both interceptors are used, this `post_update_topic_with_metadata` interceptor runs after the + `post_update_topic` interceptor. The (possibly modified) response returned by + `post_update_topic` will be passed to + `post_update_topic_with_metadata`. + """ + return response, metadata + def pre_get_iam_policy( self, request: iam_policy_pb2.GetIamPolicyRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[iam_policy_pb2.GetIamPolicyRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + iam_policy_pb2.GetIamPolicyRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for get_iam_policy Override in a subclass to manipulate the request or metadata @@ -344,8 +555,10 @@ def post_get_iam_policy(self, response: policy_pb2.Policy) -> policy_pb2.Policy: def pre_set_iam_policy( self, request: iam_policy_pb2.SetIamPolicyRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[iam_policy_pb2.SetIamPolicyRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + iam_policy_pb2.SetIamPolicyRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for set_iam_policy Override in a subclass to manipulate the request or metadata @@ -365,8 +578,11 @@ def post_set_iam_policy(self, response: policy_pb2.Policy) -> policy_pb2.Policy: def pre_test_iam_permissions( self, request: iam_policy_pb2.TestIamPermissionsRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[iam_policy_pb2.TestIamPermissionsRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + iam_policy_pb2.TestIamPermissionsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: """Pre-rpc interceptor for test_iam_permissions Override in a subclass to manipulate the request or metadata @@ -506,7 +722,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Topic: r"""Call the create topic method over HTTP. @@ -516,8 +732,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.pubsub.Topic: @@ -527,6 +745,7 @@ def __call__( http_options = ( _BasePublisherRestTransport._BaseCreateTopic._get_http_options() ) + request, metadata = self._interceptor.pre_create_topic(request, metadata) transcoded_request = ( _BasePublisherRestTransport._BaseCreateTopic._get_transcoded_request( @@ -545,6 +764,33 @@ def __call__( ) ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.PublisherClient.CreateTopic", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "CreateTopic", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = PublisherRestTransport._CreateTopic._get_response( self._host, @@ -566,7 +812,33 @@ def __call__( pb_resp = pubsub.Topic.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_topic(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_topic_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = pubsub.Topic.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.PublisherClient.create_topic", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "CreateTopic", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _DeleteTopic(_BasePublisherRestTransport._BaseDeleteTopic, PublisherRestStub): @@ -601,7 +873,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ): r"""Call the delete topic method over HTTP. @@ -611,13 +883,16 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ http_options = ( _BasePublisherRestTransport._BaseDeleteTopic._get_http_options() ) + request, metadata = self._interceptor.pre_delete_topic(request, metadata) transcoded_request = ( _BasePublisherRestTransport._BaseDeleteTopic._get_transcoded_request( @@ -632,6 +907,33 @@ def __call__( ) ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.PublisherClient.DeleteTopic", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "DeleteTopic", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = PublisherRestTransport._DeleteTopic._get_response( self._host, @@ -681,7 +983,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.DetachSubscriptionResponse: r"""Call the detach subscription method over HTTP. @@ -692,8 +994,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.pubsub.DetachSubscriptionResponse: @@ -705,6 +1009,7 @@ def __call__( http_options = ( _BasePublisherRestTransport._BaseDetachSubscription._get_http_options() ) + request, metadata = self._interceptor.pre_detach_subscription( request, metadata ) @@ -717,6 +1022,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.PublisherClient.DetachSubscription", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "DetachSubscription", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = PublisherRestTransport._DetachSubscription._get_response( self._host, @@ -737,7 +1069,35 @@ def __call__( pb_resp = pubsub.DetachSubscriptionResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_detach_subscription(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_detach_subscription_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = pubsub.DetachSubscriptionResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.PublisherClient.detach_subscription", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "DetachSubscription", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _GetTopic(_BasePublisherRestTransport._BaseGetTopic, PublisherRestStub): @@ -772,7 +1132,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Topic: r"""Call the get topic method over HTTP. @@ -782,8 +1142,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.pubsub.Topic: @@ -791,6 +1153,7 @@ def __call__( """ http_options = _BasePublisherRestTransport._BaseGetTopic._get_http_options() + request, metadata = self._interceptor.pre_get_topic(request, metadata) transcoded_request = ( _BasePublisherRestTransport._BaseGetTopic._get_transcoded_request( @@ -805,6 +1168,33 @@ def __call__( ) ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.PublisherClient.GetTopic", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "GetTopic", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = PublisherRestTransport._GetTopic._get_response( self._host, @@ -825,7 +1215,33 @@ def __call__( pb_resp = pubsub.Topic.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_topic(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_topic_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = pubsub.Topic.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.PublisherClient.get_topic", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "GetTopic", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListTopics(_BasePublisherRestTransport._BaseListTopics, PublisherRestStub): @@ -860,7 +1276,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.ListTopicsResponse: r"""Call the list topics method over HTTP. @@ -870,8 +1286,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.pubsub.ListTopicsResponse: @@ -881,6 +1299,7 @@ def __call__( http_options = ( _BasePublisherRestTransport._BaseListTopics._get_http_options() ) + request, metadata = self._interceptor.pre_list_topics(request, metadata) transcoded_request = ( _BasePublisherRestTransport._BaseListTopics._get_transcoded_request( @@ -895,6 +1314,33 @@ def __call__( ) ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.PublisherClient.ListTopics", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "ListTopics", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = PublisherRestTransport._ListTopics._get_response( self._host, @@ -915,7 +1361,33 @@ def __call__( pb_resp = pubsub.ListTopicsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_topics(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_topics_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = pubsub.ListTopicsResponse.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.PublisherClient.list_topics", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "ListTopics", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListTopicSnapshots( @@ -952,7 +1424,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.ListTopicSnapshotsResponse: r"""Call the list topic snapshots method over HTTP. @@ -962,8 +1434,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.pubsub.ListTopicSnapshotsResponse: @@ -973,6 +1447,7 @@ def __call__( http_options = ( _BasePublisherRestTransport._BaseListTopicSnapshots._get_http_options() ) + request, metadata = self._interceptor.pre_list_topic_snapshots( request, metadata ) @@ -985,6 +1460,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.PublisherClient.ListTopicSnapshots", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "ListTopicSnapshots", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = PublisherRestTransport._ListTopicSnapshots._get_response( self._host, @@ -1005,7 +1507,35 @@ def __call__( pb_resp = pubsub.ListTopicSnapshotsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_topic_snapshots(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_topic_snapshots_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = pubsub.ListTopicSnapshotsResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.PublisherClient.list_topic_snapshots", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "ListTopicSnapshots", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListTopicSubscriptions( @@ -1042,7 +1572,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.ListTopicSubscriptionsResponse: r"""Call the list topic subscriptions method over HTTP. @@ -1052,8 +1582,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.pubsub.ListTopicSubscriptionsResponse: @@ -1063,6 +1595,7 @@ def __call__( http_options = ( _BasePublisherRestTransport._BaseListTopicSubscriptions._get_http_options() ) + request, metadata = self._interceptor.pre_list_topic_subscriptions( request, metadata ) @@ -1075,6 +1608,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.PublisherClient.ListTopicSubscriptions", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "ListTopicSubscriptions", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = PublisherRestTransport._ListTopicSubscriptions._get_response( self._host, @@ -1095,7 +1655,35 @@ def __call__( pb_resp = pubsub.ListTopicSubscriptionsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_topic_subscriptions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_topic_subscriptions_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = pubsub.ListTopicSubscriptionsResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.PublisherClient.list_topic_subscriptions", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "ListTopicSubscriptions", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _Publish(_BasePublisherRestTransport._BasePublish, PublisherRestStub): @@ -1131,7 +1719,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.PublishResponse: r"""Call the publish method over HTTP. @@ -1141,8 +1729,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.pubsub.PublishResponse: @@ -1150,6 +1740,7 @@ def __call__( """ http_options = _BasePublisherRestTransport._BasePublish._get_http_options() + request, metadata = self._interceptor.pre_publish(request, metadata) transcoded_request = ( _BasePublisherRestTransport._BasePublish._get_transcoded_request( @@ -1168,6 +1759,33 @@ def __call__( ) ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.PublisherClient.Publish", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "Publish", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = PublisherRestTransport._Publish._get_response( self._host, @@ -1189,7 +1807,33 @@ def __call__( pb_resp = pubsub.PublishResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_publish(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_publish_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = pubsub.PublishResponse.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.PublisherClient.publish", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "Publish", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _UpdateTopic(_BasePublisherRestTransport._BaseUpdateTopic, PublisherRestStub): @@ -1225,7 +1869,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Topic: r"""Call the update topic method over HTTP. @@ -1235,8 +1879,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.pubsub.Topic: @@ -1246,6 +1892,7 @@ def __call__( http_options = ( _BasePublisherRestTransport._BaseUpdateTopic._get_http_options() ) + request, metadata = self._interceptor.pre_update_topic(request, metadata) transcoded_request = ( _BasePublisherRestTransport._BaseUpdateTopic._get_transcoded_request( @@ -1264,6 +1911,33 @@ def __call__( ) ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.PublisherClient.UpdateTopic", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "UpdateTopic", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = PublisherRestTransport._UpdateTopic._get_response( self._host, @@ -1285,7 +1959,33 @@ def __call__( pb_resp = pubsub.Topic.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_topic(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_topic_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = pubsub.Topic.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.PublisherClient.update_topic", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "UpdateTopic", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property @@ -1394,7 +2094,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> policy_pb2.Policy: r"""Call the get iam policy method over HTTP. @@ -1404,8 +2104,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: policy_pb2.Policy: Response from GetIamPolicy method. @@ -1414,6 +2116,7 @@ def __call__( http_options = ( _BasePublisherRestTransport._BaseGetIamPolicy._get_http_options() ) + request, metadata = self._interceptor.pre_get_iam_policy(request, metadata) transcoded_request = ( _BasePublisherRestTransport._BaseGetIamPolicy._get_transcoded_request( @@ -1428,6 +2131,33 @@ def __call__( ) ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.PublisherClient.GetIamPolicy", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "GetIamPolicy", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = PublisherRestTransport._GetIamPolicy._get_response( self._host, @@ -1447,6 +2177,27 @@ def __call__( resp = policy_pb2.Policy() resp = json_format.Parse(content, resp) resp = self._interceptor.post_get_iam_policy(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.PublisherAsyncClient.GetIamPolicy", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "GetIamPolicy", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) return resp @property @@ -1488,7 +2239,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> policy_pb2.Policy: r"""Call the set iam policy method over HTTP. @@ -1498,8 +2249,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: policy_pb2.Policy: Response from SetIamPolicy method. @@ -1508,6 +2261,7 @@ def __call__( http_options = ( _BasePublisherRestTransport._BaseSetIamPolicy._get_http_options() ) + request, metadata = self._interceptor.pre_set_iam_policy(request, metadata) transcoded_request = ( _BasePublisherRestTransport._BaseSetIamPolicy._get_transcoded_request( @@ -1526,6 +2280,33 @@ def __call__( ) ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.PublisherClient.SetIamPolicy", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "SetIamPolicy", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = PublisherRestTransport._SetIamPolicy._get_response( self._host, @@ -1546,6 +2327,27 @@ def __call__( resp = policy_pb2.Policy() resp = json_format.Parse(content, resp) resp = self._interceptor.post_set_iam_policy(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.PublisherAsyncClient.SetIamPolicy", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "SetIamPolicy", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) return resp @property @@ -1587,7 +2389,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> iam_policy_pb2.TestIamPermissionsResponse: r"""Call the test iam permissions method over HTTP. @@ -1597,8 +2399,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: iam_policy_pb2.TestIamPermissionsResponse: Response from TestIamPermissions method. @@ -1607,6 +2411,7 @@ def __call__( http_options = ( _BasePublisherRestTransport._BaseTestIamPermissions._get_http_options() ) + request, metadata = self._interceptor.pre_test_iam_permissions( request, metadata ) @@ -1623,6 +2428,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.PublisherClient.TestIamPermissions", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "TestIamPermissions", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = PublisherRestTransport._TestIamPermissions._get_response( self._host, @@ -1643,6 +2475,27 @@ def __call__( resp = iam_policy_pb2.TestIamPermissionsResponse() resp = json_format.Parse(content, resp) resp = self._interceptor.post_test_iam_permissions(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.PublisherAsyncClient.TestIamPermissions", + extra={ + "serviceName": "google.pubsub.v1.Publisher", + "rpcName": "TestIamPermissions", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) return resp @property diff --git a/google/pubsub_v1/services/schema_service/async_client.py b/google/pubsub_v1/services/schema_service/async_client.py index 2d160b062..a6ae46bae 100644 --- a/google/pubsub_v1/services/schema_service/async_client.py +++ b/google/pubsub_v1/services/schema_service/async_client.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import logging as std_logging from collections import OrderedDict import re from typing import ( @@ -53,6 +54,15 @@ from .transports.grpc_asyncio import SchemaServiceGrpcAsyncIOTransport from .client import SchemaServiceClient +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + class SchemaServiceAsyncClient: """Service for doing schema-related operations.""" @@ -258,6 +268,28 @@ def __init__( client_info=client_info, ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.pubsub_v1.SchemaServiceAsyncClient`.", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "universeDomain": getattr( + self._client._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._client._transport._credentials).__module__}.{type(self._client._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._client._transport, "_credentials") + else { + "serviceName": "google.pubsub.v1.SchemaService", + "credentialsType": None, + }, + ) + async def create_schema( self, request: Optional[Union[gp_schema.CreateSchemaRequest, dict]] = None, @@ -267,7 +299,7 @@ async def create_schema( schema_id: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> gp_schema.Schema: r"""Creates a schema. @@ -335,8 +367,10 @@ async def sample_create_schema(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Schema: @@ -399,7 +433,7 @@ async def get_schema( name: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> schema.Schema: r"""Gets a schema. @@ -442,8 +476,10 @@ async def sample_get_schema(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Schema: @@ -502,7 +538,7 @@ async def list_schemas( parent: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListSchemasAsyncPager: r"""Lists schemas in a project. @@ -546,8 +582,10 @@ async def sample_list_schemas(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.services.schema_service.pagers.ListSchemasAsyncPager: @@ -621,7 +659,7 @@ async def list_schema_revisions( name: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListSchemaRevisionsAsyncPager: r"""Lists all schema revisions for the named schema. @@ -665,8 +703,10 @@ async def sample_list_schema_revisions(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.services.schema_service.pagers.ListSchemaRevisionsAsyncPager: @@ -741,7 +781,7 @@ async def commit_schema( schema: Optional[gp_schema.Schema] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> gp_schema.Schema: r"""Commits a new schema revision to an existing schema. @@ -795,8 +835,10 @@ async def sample_commit_schema(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Schema: @@ -858,7 +900,7 @@ async def rollback_schema( revision_id: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> schema.Schema: r"""Creates a new schema revision that is a copy of the provided revision_id. @@ -913,8 +955,10 @@ async def sample_rollback_schema(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Schema: @@ -976,7 +1020,7 @@ async def delete_schema_revision( revision_id: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> schema.Schema: r"""Deletes a specific schema revision. @@ -1029,8 +1073,10 @@ async def sample_delete_schema_revision(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Schema: @@ -1091,7 +1137,7 @@ async def delete_schema( name: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> None: r"""Deletes a schema. @@ -1131,8 +1177,10 @@ async def sample_delete_schema(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have @@ -1185,7 +1233,7 @@ async def validate_schema( schema: Optional[gp_schema.Schema] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> gp_schema.ValidateSchemaResponse: r"""Validates a schema. @@ -1239,8 +1287,10 @@ async def sample_validate_schema(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.ValidateSchemaResponse: @@ -1302,7 +1352,7 @@ async def validate_message( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> schema.ValidateMessageResponse: r"""Validates a message against a schema. @@ -1339,8 +1389,10 @@ async def sample_validate_message(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.ValidateMessageResponse: @@ -1386,7 +1438,7 @@ async def set_iam_policy( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> policy_pb2.Policy: r"""Sets the IAM access control policy on the specified function. @@ -1399,8 +1451,10 @@ async def set_iam_policy( retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.policy_pb2.Policy: Defines an Identity and Access Management (IAM) policy. @@ -1504,7 +1558,7 @@ async def get_iam_policy( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> policy_pb2.Policy: r"""Gets the IAM access control policy for a function. @@ -1518,8 +1572,10 @@ async def get_iam_policy( retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.policy_pb2.Policy: Defines an Identity and Access Management (IAM) policy. @@ -1624,7 +1680,7 @@ async def test_iam_permissions( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> iam_policy_pb2.TestIamPermissionsResponse: r"""Tests the specified permissions against the IAM access control policy for a function. @@ -1639,8 +1695,10 @@ async def test_iam_permissions( retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~iam_policy_pb2.PolicyTestIamPermissionsResponse: Response message for ``TestIamPermissions`` method. diff --git a/google/pubsub_v1/services/schema_service/client.py b/google/pubsub_v1/services/schema_service/client.py index c56f8a4f3..70654560c 100644 --- a/google/pubsub_v1/services/schema_service/client.py +++ b/google/pubsub_v1/services/schema_service/client.py @@ -14,6 +14,9 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging import functools import os import re @@ -49,6 +52,15 @@ except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore from google.protobuf import timestamp_pb2 # type: ignore @@ -473,6 +485,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -577,6 +616,10 @@ def __init__( # Initialize the universe domain validation. self._is_universe_domain_valid = False + if CLIENT_LOGGING_SUPPORTED: # pragma: NO COVER + # Setup logging. + client_logging.initialize_logging() + api_key_value = getattr(self._client_options, "api_key", None) if api_key_value and credentials: raise ValueError( @@ -651,6 +694,29 @@ def __init__( api_audience=self._client_options.api_audience, ) + if "async" not in str(self._transport): + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.pubsub_v1.SchemaServiceClient`.", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "universeDomain": getattr( + self._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._transport._credentials).__module__}.{type(self._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._transport, "_credentials") + else { + "serviceName": "google.pubsub.v1.SchemaService", + "credentialsType": None, + }, + ) + def create_schema( self, request: Optional[Union[gp_schema.CreateSchemaRequest, dict]] = None, @@ -660,7 +726,7 @@ def create_schema( schema_id: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> gp_schema.Schema: r"""Creates a schema. @@ -728,8 +794,10 @@ def sample_create_schema(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Schema: @@ -789,7 +857,7 @@ def get_schema( name: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> schema.Schema: r"""Gets a schema. @@ -832,8 +900,10 @@ def sample_get_schema(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Schema: @@ -889,7 +959,7 @@ def list_schemas( parent: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListSchemasPager: r"""Lists schemas in a project. @@ -933,8 +1003,10 @@ def sample_list_schemas(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.services.schema_service.pagers.ListSchemasPager: @@ -1005,7 +1077,7 @@ def list_schema_revisions( name: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListSchemaRevisionsPager: r"""Lists all schema revisions for the named schema. @@ -1049,8 +1121,10 @@ def sample_list_schema_revisions(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.services.schema_service.pagers.ListSchemaRevisionsPager: @@ -1122,7 +1196,7 @@ def commit_schema( schema: Optional[gp_schema.Schema] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> gp_schema.Schema: r"""Commits a new schema revision to an existing schema. @@ -1176,8 +1250,10 @@ def sample_commit_schema(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Schema: @@ -1236,7 +1312,7 @@ def rollback_schema( revision_id: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> schema.Schema: r"""Creates a new schema revision that is a copy of the provided revision_id. @@ -1291,8 +1367,10 @@ def sample_rollback_schema(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Schema: @@ -1351,7 +1429,7 @@ def delete_schema_revision( revision_id: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> schema.Schema: r"""Deletes a specific schema revision. @@ -1404,8 +1482,10 @@ def sample_delete_schema_revision(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Schema: @@ -1463,7 +1543,7 @@ def delete_schema( name: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> None: r"""Deletes a schema. @@ -1503,8 +1583,10 @@ def sample_delete_schema(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have @@ -1554,7 +1636,7 @@ def validate_schema( schema: Optional[gp_schema.Schema] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> gp_schema.ValidateSchemaResponse: r"""Validates a schema. @@ -1608,8 +1690,10 @@ def sample_validate_schema(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.ValidateSchemaResponse: @@ -1668,7 +1752,7 @@ def validate_message( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> schema.ValidateMessageResponse: r"""Validates a message against a schema. @@ -1705,8 +1789,10 @@ def sample_validate_message(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.ValidateMessageResponse: @@ -1763,7 +1849,7 @@ def set_iam_policy( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> policy_pb2.Policy: r"""Sets the IAM access control policy on the specified function. @@ -1776,8 +1862,10 @@ def set_iam_policy( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.policy_pb2.Policy: Defines an Identity and Access Management (IAM) policy. @@ -1869,16 +1957,20 @@ def set_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_iam_policy( self, @@ -1886,7 +1978,7 @@ def get_iam_policy( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> policy_pb2.Policy: r"""Gets the IAM access control policy for a function. @@ -1900,8 +1992,10 @@ def get_iam_policy( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.policy_pb2.Policy: Defines an Identity and Access Management (IAM) policy. @@ -1993,16 +2087,20 @@ def get_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def test_iam_permissions( self, @@ -2010,7 +2108,7 @@ def test_iam_permissions( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> iam_policy_pb2.TestIamPermissionsResponse: r"""Tests the specified IAM permissions against the IAM access control policy for a function. @@ -2025,8 +2123,10 @@ def test_iam_permissions( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.iam_policy_pb2.TestIamPermissionsResponse: Response message for ``TestIamPermissions`` method. @@ -2055,16 +2155,20 @@ def test_iam_permissions( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/google/pubsub_v1/services/schema_service/pagers.py b/google/pubsub_v1/services/schema_service/pagers.py index fa42a6b8c..8f7080b26 100644 --- a/google/pubsub_v1/services/schema_service/pagers.py +++ b/google/pubsub_v1/services/schema_service/pagers.py @@ -66,7 +66,7 @@ def __init__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = () + metadata: Sequence[Tuple[str, Union[str, bytes]]] = () ): """Instantiate the pager. @@ -80,8 +80,10 @@ def __init__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ self._method = method self._request = schema.ListSchemasRequest(request) @@ -140,7 +142,7 @@ def __init__( *, retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = () + metadata: Sequence[Tuple[str, Union[str, bytes]]] = () ): """Instantiates the pager. @@ -154,8 +156,10 @@ def __init__( retry (google.api_core.retry.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ self._method = method self._request = schema.ListSchemasRequest(request) @@ -218,7 +222,7 @@ def __init__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = () + metadata: Sequence[Tuple[str, Union[str, bytes]]] = () ): """Instantiate the pager. @@ -232,8 +236,10 @@ def __init__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ self._method = method self._request = schema.ListSchemaRevisionsRequest(request) @@ -292,7 +298,7 @@ def __init__( *, retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = () + metadata: Sequence[Tuple[str, Union[str, bytes]]] = () ): """Instantiates the pager. @@ -306,8 +312,10 @@ def __init__( retry (google.api_core.retry.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ self._method = method self._request = schema.ListSchemaRevisionsRequest(request) diff --git a/google/pubsub_v1/services/schema_service/transports/grpc.py b/google/pubsub_v1/services/schema_service/transports/grpc.py index 421879d19..854238c8e 100644 --- a/google/pubsub_v1/services/schema_service/transports/grpc.py +++ b/google/pubsub_v1/services/schema_service/transports/grpc.py @@ -13,6 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import json +import logging as std_logging +import pickle import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union @@ -21,8 +24,11 @@ import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore +import proto # type: ignore from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore @@ -31,6 +37,81 @@ from google.pubsub_v1.types import schema as gp_schema from .base import SchemaServiceTransport, DEFAULT_CLIENT_INFO +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor(grpc.UnaryUnaryClientInterceptor): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": client_call_details.method, + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + + response = continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = response.result() + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response for {client_call_details.method}.", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class SchemaServiceGrpcTransport(SchemaServiceTransport): """gRPC backend transport for SchemaService. @@ -186,7 +267,12 @@ def __init__( ], ) - # Wrap messages. This must be done after self._grpc_channel exists + self._interceptor = _LoggingClientInterceptor() + self._logged_channel = grpc.intercept_channel( + self._grpc_channel, self._interceptor + ) + + # Wrap messages. This must be done after self._logged_channel exists self._prep_wrapped_messages(client_info) @classmethod @@ -260,7 +346,7 @@ def create_schema( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_schema" not in self._stubs: - self._stubs["create_schema"] = self.grpc_channel.unary_unary( + self._stubs["create_schema"] = self._logged_channel.unary_unary( "/google.pubsub.v1.SchemaService/CreateSchema", request_serializer=gp_schema.CreateSchemaRequest.serialize, response_deserializer=gp_schema.Schema.deserialize, @@ -284,7 +370,7 @@ def get_schema(self) -> Callable[[schema.GetSchemaRequest], schema.Schema]: # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_schema" not in self._stubs: - self._stubs["get_schema"] = self.grpc_channel.unary_unary( + self._stubs["get_schema"] = self._logged_channel.unary_unary( "/google.pubsub.v1.SchemaService/GetSchema", request_serializer=schema.GetSchemaRequest.serialize, response_deserializer=schema.Schema.deserialize, @@ -310,7 +396,7 @@ def list_schemas( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_schemas" not in self._stubs: - self._stubs["list_schemas"] = self.grpc_channel.unary_unary( + self._stubs["list_schemas"] = self._logged_channel.unary_unary( "/google.pubsub.v1.SchemaService/ListSchemas", request_serializer=schema.ListSchemasRequest.serialize, response_deserializer=schema.ListSchemasResponse.deserialize, @@ -338,7 +424,7 @@ def list_schema_revisions( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_schema_revisions" not in self._stubs: - self._stubs["list_schema_revisions"] = self.grpc_channel.unary_unary( + self._stubs["list_schema_revisions"] = self._logged_channel.unary_unary( "/google.pubsub.v1.SchemaService/ListSchemaRevisions", request_serializer=schema.ListSchemaRevisionsRequest.serialize, response_deserializer=schema.ListSchemaRevisionsResponse.deserialize, @@ -364,7 +450,7 @@ def commit_schema( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "commit_schema" not in self._stubs: - self._stubs["commit_schema"] = self.grpc_channel.unary_unary( + self._stubs["commit_schema"] = self._logged_channel.unary_unary( "/google.pubsub.v1.SchemaService/CommitSchema", request_serializer=gp_schema.CommitSchemaRequest.serialize, response_deserializer=gp_schema.Schema.deserialize, @@ -391,7 +477,7 @@ def rollback_schema( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "rollback_schema" not in self._stubs: - self._stubs["rollback_schema"] = self.grpc_channel.unary_unary( + self._stubs["rollback_schema"] = self._logged_channel.unary_unary( "/google.pubsub.v1.SchemaService/RollbackSchema", request_serializer=schema.RollbackSchemaRequest.serialize, response_deserializer=schema.Schema.deserialize, @@ -417,7 +503,7 @@ def delete_schema_revision( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_schema_revision" not in self._stubs: - self._stubs["delete_schema_revision"] = self.grpc_channel.unary_unary( + self._stubs["delete_schema_revision"] = self._logged_channel.unary_unary( "/google.pubsub.v1.SchemaService/DeleteSchemaRevision", request_serializer=schema.DeleteSchemaRevisionRequest.serialize, response_deserializer=schema.Schema.deserialize, @@ -441,7 +527,7 @@ def delete_schema(self) -> Callable[[schema.DeleteSchemaRequest], empty_pb2.Empt # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_schema" not in self._stubs: - self._stubs["delete_schema"] = self.grpc_channel.unary_unary( + self._stubs["delete_schema"] = self._logged_channel.unary_unary( "/google.pubsub.v1.SchemaService/DeleteSchema", request_serializer=schema.DeleteSchemaRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -467,7 +553,7 @@ def validate_schema( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "validate_schema" not in self._stubs: - self._stubs["validate_schema"] = self.grpc_channel.unary_unary( + self._stubs["validate_schema"] = self._logged_channel.unary_unary( "/google.pubsub.v1.SchemaService/ValidateSchema", request_serializer=gp_schema.ValidateSchemaRequest.serialize, response_deserializer=gp_schema.ValidateSchemaResponse.deserialize, @@ -493,7 +579,7 @@ def validate_message( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "validate_message" not in self._stubs: - self._stubs["validate_message"] = self.grpc_channel.unary_unary( + self._stubs["validate_message"] = self._logged_channel.unary_unary( "/google.pubsub.v1.SchemaService/ValidateMessage", request_serializer=schema.ValidateMessageRequest.serialize, response_deserializer=schema.ValidateMessageResponse.deserialize, @@ -518,7 +604,7 @@ def set_iam_policy( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "set_iam_policy" not in self._stubs: - self._stubs["set_iam_policy"] = self.grpc_channel.unary_unary( + self._stubs["set_iam_policy"] = self._logged_channel.unary_unary( "/google.iam.v1.IAMPolicy/SetIamPolicy", request_serializer=iam_policy_pb2.SetIamPolicyRequest.SerializeToString, response_deserializer=policy_pb2.Policy.FromString, @@ -544,7 +630,7 @@ def get_iam_policy( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_iam_policy" not in self._stubs: - self._stubs["get_iam_policy"] = self.grpc_channel.unary_unary( + self._stubs["get_iam_policy"] = self._logged_channel.unary_unary( "/google.iam.v1.IAMPolicy/GetIamPolicy", request_serializer=iam_policy_pb2.GetIamPolicyRequest.SerializeToString, response_deserializer=policy_pb2.Policy.FromString, @@ -573,7 +659,7 @@ def test_iam_permissions( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "test_iam_permissions" not in self._stubs: - self._stubs["test_iam_permissions"] = self.grpc_channel.unary_unary( + self._stubs["test_iam_permissions"] = self._logged_channel.unary_unary( "/google.iam.v1.IAMPolicy/TestIamPermissions", request_serializer=iam_policy_pb2.TestIamPermissionsRequest.SerializeToString, response_deserializer=iam_policy_pb2.TestIamPermissionsResponse.FromString, @@ -581,7 +667,7 @@ def test_iam_permissions( return self._stubs["test_iam_permissions"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/google/pubsub_v1/services/schema_service/transports/grpc_asyncio.py b/google/pubsub_v1/services/schema_service/transports/grpc_asyncio.py index e642ed1b9..a6a27995c 100644 --- a/google/pubsub_v1/services/schema_service/transports/grpc_asyncio.py +++ b/google/pubsub_v1/services/schema_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import pickle +import logging as std_logging import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union @@ -23,8 +26,11 @@ from google.api_core import retry_async as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore +import proto # type: ignore from grpc.experimental import aio # type: ignore from google.iam.v1 import iam_policy_pb2 # type: ignore @@ -35,6 +41,82 @@ from .base import SchemaServiceTransport, DEFAULT_CLIENT_INFO from .grpc import SchemaServiceGrpcTransport +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientAIOInterceptor( + grpc.aio.UnaryUnaryClientInterceptor +): # pragma: NO COVER + async def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": str(client_call_details.method), + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + response = await continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = await response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = await response + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response to rpc {client_call_details.method}.", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class SchemaServiceGrpcAsyncIOTransport(SchemaServiceTransport): """gRPC AsyncIO backend transport for SchemaService. @@ -233,10 +315,13 @@ def __init__( ], ) - # Wrap messages. This must be done after self._grpc_channel exists + self._interceptor = _LoggingClientAIOInterceptor() + self._grpc_channel._unary_unary_interceptors.append(self._interceptor) + self._logged_channel = self._grpc_channel self._wrap_with_kind = ( "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters ) + # Wrap messages. This must be done after self._logged_channel exists self._prep_wrapped_messages(client_info) @property @@ -268,7 +353,7 @@ def create_schema( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_schema" not in self._stubs: - self._stubs["create_schema"] = self.grpc_channel.unary_unary( + self._stubs["create_schema"] = self._logged_channel.unary_unary( "/google.pubsub.v1.SchemaService/CreateSchema", request_serializer=gp_schema.CreateSchemaRequest.serialize, response_deserializer=gp_schema.Schema.deserialize, @@ -294,7 +379,7 @@ def get_schema( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_schema" not in self._stubs: - self._stubs["get_schema"] = self.grpc_channel.unary_unary( + self._stubs["get_schema"] = self._logged_channel.unary_unary( "/google.pubsub.v1.SchemaService/GetSchema", request_serializer=schema.GetSchemaRequest.serialize, response_deserializer=schema.Schema.deserialize, @@ -320,7 +405,7 @@ def list_schemas( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_schemas" not in self._stubs: - self._stubs["list_schemas"] = self.grpc_channel.unary_unary( + self._stubs["list_schemas"] = self._logged_channel.unary_unary( "/google.pubsub.v1.SchemaService/ListSchemas", request_serializer=schema.ListSchemasRequest.serialize, response_deserializer=schema.ListSchemasResponse.deserialize, @@ -349,7 +434,7 @@ def list_schema_revisions( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_schema_revisions" not in self._stubs: - self._stubs["list_schema_revisions"] = self.grpc_channel.unary_unary( + self._stubs["list_schema_revisions"] = self._logged_channel.unary_unary( "/google.pubsub.v1.SchemaService/ListSchemaRevisions", request_serializer=schema.ListSchemaRevisionsRequest.serialize, response_deserializer=schema.ListSchemaRevisionsResponse.deserialize, @@ -375,7 +460,7 @@ def commit_schema( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "commit_schema" not in self._stubs: - self._stubs["commit_schema"] = self.grpc_channel.unary_unary( + self._stubs["commit_schema"] = self._logged_channel.unary_unary( "/google.pubsub.v1.SchemaService/CommitSchema", request_serializer=gp_schema.CommitSchemaRequest.serialize, response_deserializer=gp_schema.Schema.deserialize, @@ -402,7 +487,7 @@ def rollback_schema( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "rollback_schema" not in self._stubs: - self._stubs["rollback_schema"] = self.grpc_channel.unary_unary( + self._stubs["rollback_schema"] = self._logged_channel.unary_unary( "/google.pubsub.v1.SchemaService/RollbackSchema", request_serializer=schema.RollbackSchemaRequest.serialize, response_deserializer=schema.Schema.deserialize, @@ -428,7 +513,7 @@ def delete_schema_revision( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_schema_revision" not in self._stubs: - self._stubs["delete_schema_revision"] = self.grpc_channel.unary_unary( + self._stubs["delete_schema_revision"] = self._logged_channel.unary_unary( "/google.pubsub.v1.SchemaService/DeleteSchemaRevision", request_serializer=schema.DeleteSchemaRevisionRequest.serialize, response_deserializer=schema.Schema.deserialize, @@ -454,7 +539,7 @@ def delete_schema( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_schema" not in self._stubs: - self._stubs["delete_schema"] = self.grpc_channel.unary_unary( + self._stubs["delete_schema"] = self._logged_channel.unary_unary( "/google.pubsub.v1.SchemaService/DeleteSchema", request_serializer=schema.DeleteSchemaRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -482,7 +567,7 @@ def validate_schema( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "validate_schema" not in self._stubs: - self._stubs["validate_schema"] = self.grpc_channel.unary_unary( + self._stubs["validate_schema"] = self._logged_channel.unary_unary( "/google.pubsub.v1.SchemaService/ValidateSchema", request_serializer=gp_schema.ValidateSchemaRequest.serialize, response_deserializer=gp_schema.ValidateSchemaResponse.deserialize, @@ -510,7 +595,7 @@ def validate_message( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "validate_message" not in self._stubs: - self._stubs["validate_message"] = self.grpc_channel.unary_unary( + self._stubs["validate_message"] = self._logged_channel.unary_unary( "/google.pubsub.v1.SchemaService/ValidateMessage", request_serializer=schema.ValidateMessageRequest.serialize, response_deserializer=schema.ValidateMessageResponse.deserialize, @@ -535,7 +620,7 @@ def set_iam_policy( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "set_iam_policy" not in self._stubs: - self._stubs["set_iam_policy"] = self.grpc_channel.unary_unary( + self._stubs["set_iam_policy"] = self._logged_channel.unary_unary( "/google.iam.v1.IAMPolicy/SetIamPolicy", request_serializer=iam_policy_pb2.SetIamPolicyRequest.SerializeToString, response_deserializer=policy_pb2.Policy.FromString, @@ -561,7 +646,7 @@ def get_iam_policy( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_iam_policy" not in self._stubs: - self._stubs["get_iam_policy"] = self.grpc_channel.unary_unary( + self._stubs["get_iam_policy"] = self._logged_channel.unary_unary( "/google.iam.v1.IAMPolicy/GetIamPolicy", request_serializer=iam_policy_pb2.GetIamPolicyRequest.SerializeToString, response_deserializer=policy_pb2.Policy.FromString, @@ -590,7 +675,7 @@ def test_iam_permissions( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "test_iam_permissions" not in self._stubs: - self._stubs["test_iam_permissions"] = self.grpc_channel.unary_unary( + self._stubs["test_iam_permissions"] = self._logged_channel.unary_unary( "/google.iam.v1.IAMPolicy/TestIamPermissions", request_serializer=iam_policy_pb2.TestIamPermissionsRequest.SerializeToString, response_deserializer=iam_policy_pb2.TestIamPermissionsResponse.FromString, @@ -763,7 +848,7 @@ def _wrap_method(self, func, *args, **kwargs): return gapic_v1.method_async.wrap_method(func, *args, **kwargs) def close(self): - return self.grpc_channel.close() + return self._logged_channel.close() @property def kind(self) -> str: diff --git a/google/pubsub_v1/services/schema_service/transports/rest.py b/google/pubsub_v1/services/schema_service/transports/rest.py index 7cf86c808..873e0729d 100644 --- a/google/pubsub_v1/services/schema_service/transports/rest.py +++ b/google/pubsub_v1/services/schema_service/transports/rest.py @@ -13,9 +13,10 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import logging +import json # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore -import json # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries @@ -48,6 +49,14 @@ except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = logging.getLogger(__name__) DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, @@ -156,8 +165,8 @@ def post_validate_schema(self, response): def pre_commit_schema( self, request: gp_schema.CommitSchemaRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[gp_schema.CommitSchemaRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gp_schema.CommitSchemaRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for commit_schema Override in a subclass to manipulate the request or metadata @@ -168,17 +177,40 @@ def pre_commit_schema( def post_commit_schema(self, response: gp_schema.Schema) -> gp_schema.Schema: """Post-rpc interceptor for commit_schema - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_commit_schema_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_commit_schema` interceptor runs + before the `post_commit_schema_with_metadata` interceptor. """ return response + def post_commit_schema_with_metadata( + self, + response: gp_schema.Schema, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gp_schema.Schema, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for commit_schema + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_commit_schema_with_metadata` + interceptor in new development instead of the `post_commit_schema` interceptor. + When both interceptors are used, this `post_commit_schema_with_metadata` interceptor runs after the + `post_commit_schema` interceptor. The (possibly modified) response returned by + `post_commit_schema` will be passed to + `post_commit_schema_with_metadata`. + """ + return response, metadata + def pre_create_schema( self, request: gp_schema.CreateSchemaRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[gp_schema.CreateSchemaRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gp_schema.CreateSchemaRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for create_schema Override in a subclass to manipulate the request or metadata @@ -189,15 +221,40 @@ def pre_create_schema( def post_create_schema(self, response: gp_schema.Schema) -> gp_schema.Schema: """Post-rpc interceptor for create_schema - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_schema_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_create_schema` interceptor runs + before the `post_create_schema_with_metadata` interceptor. """ return response + def post_create_schema_with_metadata( + self, + response: gp_schema.Schema, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gp_schema.Schema, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_schema + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_create_schema_with_metadata` + interceptor in new development instead of the `post_create_schema` interceptor. + When both interceptors are used, this `post_create_schema_with_metadata` interceptor runs after the + `post_create_schema` interceptor. The (possibly modified) response returned by + `post_create_schema` will be passed to + `post_create_schema_with_metadata`. + """ + return response, metadata + def pre_delete_schema( - self, request: schema.DeleteSchemaRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[schema.DeleteSchemaRequest, Sequence[Tuple[str, str]]]: + self, + request: schema.DeleteSchemaRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[schema.DeleteSchemaRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for delete_schema Override in a subclass to manipulate the request or metadata @@ -208,8 +265,10 @@ def pre_delete_schema( def pre_delete_schema_revision( self, request: schema.DeleteSchemaRevisionRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[schema.DeleteSchemaRevisionRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + schema.DeleteSchemaRevisionRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for delete_schema_revision Override in a subclass to manipulate the request or metadata @@ -220,15 +279,38 @@ def pre_delete_schema_revision( def post_delete_schema_revision(self, response: schema.Schema) -> schema.Schema: """Post-rpc interceptor for delete_schema_revision - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_schema_revision_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_delete_schema_revision` interceptor runs + before the `post_delete_schema_revision_with_metadata` interceptor. """ return response + def post_delete_schema_revision_with_metadata( + self, response: schema.Schema, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[schema.Schema, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_schema_revision + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_delete_schema_revision_with_metadata` + interceptor in new development instead of the `post_delete_schema_revision` interceptor. + When both interceptors are used, this `post_delete_schema_revision_with_metadata` interceptor runs after the + `post_delete_schema_revision` interceptor. The (possibly modified) response returned by + `post_delete_schema_revision` will be passed to + `post_delete_schema_revision_with_metadata`. + """ + return response, metadata + def pre_get_schema( - self, request: schema.GetSchemaRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[schema.GetSchemaRequest, Sequence[Tuple[str, str]]]: + self, + request: schema.GetSchemaRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[schema.GetSchemaRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for get_schema Override in a subclass to manipulate the request or metadata @@ -239,17 +321,40 @@ def pre_get_schema( def post_get_schema(self, response: schema.Schema) -> schema.Schema: """Post-rpc interceptor for get_schema - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_schema_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_get_schema` interceptor runs + before the `post_get_schema_with_metadata` interceptor. """ return response + def post_get_schema_with_metadata( + self, response: schema.Schema, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[schema.Schema, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_schema + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_get_schema_with_metadata` + interceptor in new development instead of the `post_get_schema` interceptor. + When both interceptors are used, this `post_get_schema_with_metadata` interceptor runs after the + `post_get_schema` interceptor. The (possibly modified) response returned by + `post_get_schema` will be passed to + `post_get_schema_with_metadata`. + """ + return response, metadata + def pre_list_schema_revisions( self, request: schema.ListSchemaRevisionsRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[schema.ListSchemaRevisionsRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + schema.ListSchemaRevisionsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for list_schema_revisions Override in a subclass to manipulate the request or metadata @@ -262,15 +367,42 @@ def post_list_schema_revisions( ) -> schema.ListSchemaRevisionsResponse: """Post-rpc interceptor for list_schema_revisions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_schema_revisions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_list_schema_revisions` interceptor runs + before the `post_list_schema_revisions_with_metadata` interceptor. """ return response + def post_list_schema_revisions_with_metadata( + self, + response: schema.ListSchemaRevisionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + schema.ListSchemaRevisionsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_schema_revisions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_list_schema_revisions_with_metadata` + interceptor in new development instead of the `post_list_schema_revisions` interceptor. + When both interceptors are used, this `post_list_schema_revisions_with_metadata` interceptor runs after the + `post_list_schema_revisions` interceptor. The (possibly modified) response returned by + `post_list_schema_revisions` will be passed to + `post_list_schema_revisions_with_metadata`. + """ + return response, metadata + def pre_list_schemas( - self, request: schema.ListSchemasRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[schema.ListSchemasRequest, Sequence[Tuple[str, str]]]: + self, + request: schema.ListSchemasRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[schema.ListSchemasRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for list_schemas Override in a subclass to manipulate the request or metadata @@ -283,15 +415,40 @@ def post_list_schemas( ) -> schema.ListSchemasResponse: """Post-rpc interceptor for list_schemas - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_schemas_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_list_schemas` interceptor runs + before the `post_list_schemas_with_metadata` interceptor. """ return response + def post_list_schemas_with_metadata( + self, + response: schema.ListSchemasResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[schema.ListSchemasResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_schemas + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_list_schemas_with_metadata` + interceptor in new development instead of the `post_list_schemas` interceptor. + When both interceptors are used, this `post_list_schemas_with_metadata` interceptor runs after the + `post_list_schemas` interceptor. The (possibly modified) response returned by + `post_list_schemas` will be passed to + `post_list_schemas_with_metadata`. + """ + return response, metadata + def pre_rollback_schema( - self, request: schema.RollbackSchemaRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[schema.RollbackSchemaRequest, Sequence[Tuple[str, str]]]: + self, + request: schema.RollbackSchemaRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[schema.RollbackSchemaRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for rollback_schema Override in a subclass to manipulate the request or metadata @@ -302,17 +459,38 @@ def pre_rollback_schema( def post_rollback_schema(self, response: schema.Schema) -> schema.Schema: """Post-rpc interceptor for rollback_schema - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_rollback_schema_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_rollback_schema` interceptor runs + before the `post_rollback_schema_with_metadata` interceptor. """ return response + def post_rollback_schema_with_metadata( + self, response: schema.Schema, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[schema.Schema, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for rollback_schema + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_rollback_schema_with_metadata` + interceptor in new development instead of the `post_rollback_schema` interceptor. + When both interceptors are used, this `post_rollback_schema_with_metadata` interceptor runs after the + `post_rollback_schema` interceptor. The (possibly modified) response returned by + `post_rollback_schema` will be passed to + `post_rollback_schema_with_metadata`. + """ + return response, metadata + def pre_validate_message( self, request: schema.ValidateMessageRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[schema.ValidateMessageRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[schema.ValidateMessageRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for validate_message Override in a subclass to manipulate the request or metadata @@ -325,17 +503,42 @@ def post_validate_message( ) -> schema.ValidateMessageResponse: """Post-rpc interceptor for validate_message - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_validate_message_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_validate_message` interceptor runs + before the `post_validate_message_with_metadata` interceptor. """ return response + def post_validate_message_with_metadata( + self, + response: schema.ValidateMessageResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[schema.ValidateMessageResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for validate_message + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_validate_message_with_metadata` + interceptor in new development instead of the `post_validate_message` interceptor. + When both interceptors are used, this `post_validate_message_with_metadata` interceptor runs after the + `post_validate_message` interceptor. The (possibly modified) response returned by + `post_validate_message` will be passed to + `post_validate_message_with_metadata`. + """ + return response, metadata + def pre_validate_schema( self, request: gp_schema.ValidateSchemaRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[gp_schema.ValidateSchemaRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gp_schema.ValidateSchemaRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for validate_schema Override in a subclass to manipulate the request or metadata @@ -348,17 +551,44 @@ def post_validate_schema( ) -> gp_schema.ValidateSchemaResponse: """Post-rpc interceptor for validate_schema - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_validate_schema_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_validate_schema` interceptor runs + before the `post_validate_schema_with_metadata` interceptor. """ return response + def post_validate_schema_with_metadata( + self, + response: gp_schema.ValidateSchemaResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gp_schema.ValidateSchemaResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for validate_schema + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_validate_schema_with_metadata` + interceptor in new development instead of the `post_validate_schema` interceptor. + When both interceptors are used, this `post_validate_schema_with_metadata` interceptor runs after the + `post_validate_schema` interceptor. The (possibly modified) response returned by + `post_validate_schema` will be passed to + `post_validate_schema_with_metadata`. + """ + return response, metadata + def pre_get_iam_policy( self, request: iam_policy_pb2.GetIamPolicyRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[iam_policy_pb2.GetIamPolicyRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + iam_policy_pb2.GetIamPolicyRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for get_iam_policy Override in a subclass to manipulate the request or metadata @@ -378,8 +608,10 @@ def post_get_iam_policy(self, response: policy_pb2.Policy) -> policy_pb2.Policy: def pre_set_iam_policy( self, request: iam_policy_pb2.SetIamPolicyRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[iam_policy_pb2.SetIamPolicyRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + iam_policy_pb2.SetIamPolicyRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for set_iam_policy Override in a subclass to manipulate the request or metadata @@ -399,8 +631,11 @@ def post_set_iam_policy(self, response: policy_pb2.Policy) -> policy_pb2.Policy: def pre_test_iam_permissions( self, request: iam_policy_pb2.TestIamPermissionsRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[iam_policy_pb2.TestIamPermissionsRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + iam_policy_pb2.TestIamPermissionsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: """Pre-rpc interceptor for test_iam_permissions Override in a subclass to manipulate the request or metadata @@ -541,7 +776,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> gp_schema.Schema: r"""Call the commit schema method over HTTP. @@ -551,8 +786,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.gp_schema.Schema: @@ -562,6 +799,7 @@ def __call__( http_options = ( _BaseSchemaServiceRestTransport._BaseCommitSchema._get_http_options() ) + request, metadata = self._interceptor.pre_commit_schema(request, metadata) transcoded_request = _BaseSchemaServiceRestTransport._BaseCommitSchema._get_transcoded_request( http_options, request @@ -576,6 +814,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SchemaServiceClient.CommitSchema", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "CommitSchema", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SchemaServiceRestTransport._CommitSchema._get_response( self._host, @@ -597,7 +862,33 @@ def __call__( pb_resp = gp_schema.Schema.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_commit_schema(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_commit_schema_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = gp_schema.Schema.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SchemaServiceClient.commit_schema", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "CommitSchema", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _CreateSchema( @@ -635,7 +926,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> gp_schema.Schema: r"""Call the create schema method over HTTP. @@ -645,8 +936,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.gp_schema.Schema: @@ -656,6 +949,7 @@ def __call__( http_options = ( _BaseSchemaServiceRestTransport._BaseCreateSchema._get_http_options() ) + request, metadata = self._interceptor.pre_create_schema(request, metadata) transcoded_request = _BaseSchemaServiceRestTransport._BaseCreateSchema._get_transcoded_request( http_options, request @@ -670,6 +964,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SchemaServiceClient.CreateSchema", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "CreateSchema", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SchemaServiceRestTransport._CreateSchema._get_response( self._host, @@ -691,7 +1012,33 @@ def __call__( pb_resp = gp_schema.Schema.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_schema(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_schema_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = gp_schema.Schema.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SchemaServiceClient.create_schema", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "CreateSchema", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _DeleteSchema( @@ -728,7 +1075,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ): r"""Call the delete schema method over HTTP. @@ -738,13 +1085,16 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ http_options = ( _BaseSchemaServiceRestTransport._BaseDeleteSchema._get_http_options() ) + request, metadata = self._interceptor.pre_delete_schema(request, metadata) transcoded_request = _BaseSchemaServiceRestTransport._BaseDeleteSchema._get_transcoded_request( http_options, request @@ -755,6 +1105,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SchemaServiceClient.DeleteSchema", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "DeleteSchema", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SchemaServiceRestTransport._DeleteSchema._get_response( self._host, @@ -804,7 +1181,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> schema.Schema: r"""Call the delete schema revision method over HTTP. @@ -814,8 +1191,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.schema.Schema: @@ -825,6 +1204,7 @@ def __call__( http_options = ( _BaseSchemaServiceRestTransport._BaseDeleteSchemaRevision._get_http_options() ) + request, metadata = self._interceptor.pre_delete_schema_revision( request, metadata ) @@ -837,6 +1217,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SchemaServiceClient.DeleteSchemaRevision", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "DeleteSchemaRevision", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SchemaServiceRestTransport._DeleteSchemaRevision._get_response( self._host, @@ -857,7 +1264,33 @@ def __call__( pb_resp = schema.Schema.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_delete_schema_revision(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_schema_revision_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = schema.Schema.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SchemaServiceClient.delete_schema_revision", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "DeleteSchemaRevision", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _GetSchema( @@ -894,7 +1327,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> schema.Schema: r"""Call the get schema method over HTTP. @@ -904,8 +1337,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.schema.Schema: @@ -915,6 +1350,7 @@ def __call__( http_options = ( _BaseSchemaServiceRestTransport._BaseGetSchema._get_http_options() ) + request, metadata = self._interceptor.pre_get_schema(request, metadata) transcoded_request = ( _BaseSchemaServiceRestTransport._BaseGetSchema._get_transcoded_request( @@ -929,6 +1365,33 @@ def __call__( ) ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SchemaServiceClient.GetSchema", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "GetSchema", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SchemaServiceRestTransport._GetSchema._get_response( self._host, @@ -949,7 +1412,33 @@ def __call__( pb_resp = schema.Schema.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_schema(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_schema_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = schema.Schema.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SchemaServiceClient.get_schema", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "GetSchema", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListSchemaRevisions( @@ -986,7 +1475,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> schema.ListSchemaRevisionsResponse: r"""Call the list schema revisions method over HTTP. @@ -996,8 +1485,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.schema.ListSchemaRevisionsResponse: @@ -1007,6 +1498,7 @@ def __call__( http_options = ( _BaseSchemaServiceRestTransport._BaseListSchemaRevisions._get_http_options() ) + request, metadata = self._interceptor.pre_list_schema_revisions( request, metadata ) @@ -1019,6 +1511,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SchemaServiceClient.ListSchemaRevisions", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "ListSchemaRevisions", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SchemaServiceRestTransport._ListSchemaRevisions._get_response( self._host, @@ -1039,7 +1558,35 @@ def __call__( pb_resp = schema.ListSchemaRevisionsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_schema_revisions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_schema_revisions_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = schema.ListSchemaRevisionsResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SchemaServiceClient.list_schema_revisions", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "ListSchemaRevisions", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListSchemas( @@ -1076,7 +1623,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> schema.ListSchemasResponse: r"""Call the list schemas method over HTTP. @@ -1086,8 +1633,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.schema.ListSchemasResponse: @@ -1097,6 +1646,7 @@ def __call__( http_options = ( _BaseSchemaServiceRestTransport._BaseListSchemas._get_http_options() ) + request, metadata = self._interceptor.pre_list_schemas(request, metadata) transcoded_request = _BaseSchemaServiceRestTransport._BaseListSchemas._get_transcoded_request( http_options, request @@ -1109,6 +1659,33 @@ def __call__( ) ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SchemaServiceClient.ListSchemas", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "ListSchemas", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SchemaServiceRestTransport._ListSchemas._get_response( self._host, @@ -1129,7 +1706,33 @@ def __call__( pb_resp = schema.ListSchemasResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_schemas(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_schemas_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = schema.ListSchemasResponse.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SchemaServiceClient.list_schemas", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "ListSchemas", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _RollbackSchema( @@ -1167,7 +1770,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> schema.Schema: r"""Call the rollback schema method over HTTP. @@ -1177,8 +1780,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.schema.Schema: @@ -1188,6 +1793,7 @@ def __call__( http_options = ( _BaseSchemaServiceRestTransport._BaseRollbackSchema._get_http_options() ) + request, metadata = self._interceptor.pre_rollback_schema(request, metadata) transcoded_request = _BaseSchemaServiceRestTransport._BaseRollbackSchema._get_transcoded_request( http_options, request @@ -1202,6 +1808,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SchemaServiceClient.RollbackSchema", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "RollbackSchema", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SchemaServiceRestTransport._RollbackSchema._get_response( self._host, @@ -1223,7 +1856,33 @@ def __call__( pb_resp = schema.Schema.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_rollback_schema(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_rollback_schema_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = schema.Schema.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SchemaServiceClient.rollback_schema", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "RollbackSchema", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ValidateMessage( @@ -1261,7 +1920,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> schema.ValidateMessageResponse: r"""Call the validate message method over HTTP. @@ -1271,8 +1930,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.schema.ValidateMessageResponse: @@ -1284,6 +1945,7 @@ def __call__( http_options = ( _BaseSchemaServiceRestTransport._BaseValidateMessage._get_http_options() ) + request, metadata = self._interceptor.pre_validate_message( request, metadata ) @@ -1300,6 +1962,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SchemaServiceClient.ValidateMessage", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "ValidateMessage", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SchemaServiceRestTransport._ValidateMessage._get_response( self._host, @@ -1321,7 +2010,33 @@ def __call__( pb_resp = schema.ValidateMessageResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_validate_message(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_validate_message_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = schema.ValidateMessageResponse.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SchemaServiceClient.validate_message", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "ValidateMessage", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ValidateSchema( @@ -1359,7 +2074,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> gp_schema.ValidateSchemaResponse: r"""Call the validate schema method over HTTP. @@ -1369,8 +2084,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.gp_schema.ValidateSchemaResponse: @@ -1382,6 +2099,7 @@ def __call__( http_options = ( _BaseSchemaServiceRestTransport._BaseValidateSchema._get_http_options() ) + request, metadata = self._interceptor.pre_validate_schema(request, metadata) transcoded_request = _BaseSchemaServiceRestTransport._BaseValidateSchema._get_transcoded_request( http_options, request @@ -1396,6 +2114,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SchemaServiceClient.ValidateSchema", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "ValidateSchema", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SchemaServiceRestTransport._ValidateSchema._get_response( self._host, @@ -1417,7 +2162,35 @@ def __call__( pb_resp = gp_schema.ValidateSchemaResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_validate_schema(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_validate_schema_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = gp_schema.ValidateSchemaResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SchemaServiceClient.validate_schema", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "ValidateSchema", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property @@ -1536,7 +2309,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> policy_pb2.Policy: r"""Call the get iam policy method over HTTP. @@ -1546,8 +2319,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: policy_pb2.Policy: Response from GetIamPolicy method. @@ -1556,6 +2331,7 @@ def __call__( http_options = ( _BaseSchemaServiceRestTransport._BaseGetIamPolicy._get_http_options() ) + request, metadata = self._interceptor.pre_get_iam_policy(request, metadata) transcoded_request = _BaseSchemaServiceRestTransport._BaseGetIamPolicy._get_transcoded_request( http_options, request @@ -1566,6 +2342,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SchemaServiceClient.GetIamPolicy", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "GetIamPolicy", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SchemaServiceRestTransport._GetIamPolicy._get_response( self._host, @@ -1585,6 +2388,27 @@ def __call__( resp = policy_pb2.Policy() resp = json_format.Parse(content, resp) resp = self._interceptor.post_get_iam_policy(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SchemaServiceAsyncClient.GetIamPolicy", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "GetIamPolicy", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) return resp @property @@ -1626,7 +2450,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> policy_pb2.Policy: r"""Call the set iam policy method over HTTP. @@ -1636,8 +2460,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: policy_pb2.Policy: Response from SetIamPolicy method. @@ -1646,6 +2472,7 @@ def __call__( http_options = ( _BaseSchemaServiceRestTransport._BaseSetIamPolicy._get_http_options() ) + request, metadata = self._interceptor.pre_set_iam_policy(request, metadata) transcoded_request = _BaseSchemaServiceRestTransport._BaseSetIamPolicy._get_transcoded_request( http_options, request @@ -1660,6 +2487,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SchemaServiceClient.SetIamPolicy", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "SetIamPolicy", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SchemaServiceRestTransport._SetIamPolicy._get_response( self._host, @@ -1680,6 +2534,27 @@ def __call__( resp = policy_pb2.Policy() resp = json_format.Parse(content, resp) resp = self._interceptor.post_set_iam_policy(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SchemaServiceAsyncClient.SetIamPolicy", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "SetIamPolicy", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) return resp @property @@ -1721,7 +2596,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> iam_policy_pb2.TestIamPermissionsResponse: r"""Call the test iam permissions method over HTTP. @@ -1731,8 +2606,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: iam_policy_pb2.TestIamPermissionsResponse: Response from TestIamPermissions method. @@ -1741,6 +2618,7 @@ def __call__( http_options = ( _BaseSchemaServiceRestTransport._BaseTestIamPermissions._get_http_options() ) + request, metadata = self._interceptor.pre_test_iam_permissions( request, metadata ) @@ -1757,6 +2635,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SchemaServiceClient.TestIamPermissions", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "TestIamPermissions", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SchemaServiceRestTransport._TestIamPermissions._get_response( self._host, @@ -1777,6 +2682,27 @@ def __call__( resp = iam_policy_pb2.TestIamPermissionsResponse() resp = json_format.Parse(content, resp) resp = self._interceptor.post_test_iam_permissions(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SchemaServiceAsyncClient.TestIamPermissions", + extra={ + "serviceName": "google.pubsub.v1.SchemaService", + "rpcName": "TestIamPermissions", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) return resp @property diff --git a/google/pubsub_v1/services/subscriber/async_client.py b/google/pubsub_v1/services/subscriber/async_client.py index 7f40480ef..d2a7eedcd 100644 --- a/google/pubsub_v1/services/subscriber/async_client.py +++ b/google/pubsub_v1/services/subscriber/async_client.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import logging as std_logging from collections import OrderedDict import re from typing import ( @@ -58,6 +59,15 @@ from .transports.grpc_asyncio import SubscriberGrpcAsyncIOTransport from .client import SubscriberClient +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + class SubscriberAsyncClient: """The service that an application uses to manipulate subscriptions and @@ -265,6 +275,28 @@ def __init__( client_info=client_info, ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.pubsub_v1.SubscriberAsyncClient`.", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "universeDomain": getattr( + self._client._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._client._transport._credentials).__module__}.{type(self._client._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._client._transport, "_credentials") + else { + "serviceName": "google.pubsub.v1.Subscriber", + "credentialsType": None, + }, + ) + async def create_subscription( self, request: Optional[Union[pubsub.Subscription, dict]] = None, @@ -275,7 +307,7 @@ async def create_subscription( ack_deadline_seconds: Optional[int] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Subscription: r"""Creates a subscription to a given topic. See the [resource name rules] @@ -388,8 +420,10 @@ async def sample_create_subscription(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Subscription: @@ -458,7 +492,7 @@ async def get_subscription( subscription: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Subscription: r"""Gets the configuration details of a subscription. @@ -502,8 +536,10 @@ async def sample_get_subscription(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Subscription: @@ -569,7 +605,7 @@ async def update_subscription( update_mask: Optional[field_mask_pb2.FieldMask] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Subscription: r"""Updates an existing subscription by updating the fields specified in the update mask. Note that certain @@ -628,8 +664,10 @@ async def sample_update_subscription(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Subscription: @@ -696,7 +734,7 @@ async def list_subscriptions( project: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListSubscriptionsAsyncPager: r"""Lists matching subscriptions. @@ -740,8 +778,10 @@ async def sample_list_subscriptions(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.services.subscriber.pagers.ListSubscriptionsAsyncPager: @@ -815,7 +855,7 @@ async def delete_subscription( subscription: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> None: r"""Deletes an existing subscription. All messages retained in the subscription are immediately dropped. Calls to ``Pull`` after @@ -861,8 +901,10 @@ async def sample_delete_subscription(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have @@ -918,7 +960,7 @@ async def modify_ack_deadline( ack_deadline_seconds: Optional[int] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> None: r"""Modifies the ack deadline for a specific message. This method is useful to indicate that more time is needed to process a message @@ -987,8 +1029,10 @@ async def sample_modify_ack_deadline(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have @@ -1047,7 +1091,7 @@ async def acknowledge( ack_ids: Optional[MutableSequence[str]] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> None: r"""Acknowledges the messages associated with the ``ack_ids`` in the ``AcknowledgeRequest``. The Pub/Sub system can remove the @@ -1104,8 +1148,10 @@ async def sample_acknowledge(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have @@ -1163,7 +1209,7 @@ async def pull( max_messages: Optional[int] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.PullResponse: r"""Pulls messages from the server. @@ -1232,8 +1278,10 @@ async def sample_pull(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.PullResponse: @@ -1301,7 +1349,7 @@ def streaming_pull( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> Awaitable[AsyncIterable[pubsub.StreamingPullResponse]]: r"""Establishes a stream with the server, which sends messages down to the client. The client streams acknowledgements and ack @@ -1359,8 +1407,10 @@ def request_generator(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: AsyncIterable[google.pubsub_v1.types.StreamingPullResponse]: @@ -1397,7 +1447,7 @@ async def modify_push_config( push_config: Optional[pubsub.PushConfig] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> None: r"""Modifies the ``PushConfig`` for a specified subscription. @@ -1456,8 +1506,10 @@ async def sample_modify_push_config(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have @@ -1513,7 +1565,7 @@ async def get_snapshot( snapshot: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Snapshot: r"""Gets the configuration details of a snapshot. Snapshots are used in @@ -1561,8 +1613,10 @@ async def sample_get_snapshot(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Snapshot: @@ -1627,7 +1681,7 @@ async def list_snapshots( project: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListSnapshotsAsyncPager: r"""Lists the existing snapshots. Snapshots are used in `Seek `__ @@ -1675,8 +1729,10 @@ async def sample_list_snapshots(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.services.subscriber.pagers.ListSnapshotsAsyncPager: @@ -1751,7 +1807,7 @@ async def create_snapshot( subscription: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Snapshot: r"""Creates a snapshot from the requested subscription. Snapshots are used in @@ -1834,8 +1890,10 @@ async def sample_create_snapshot(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Snapshot: @@ -1903,7 +1961,7 @@ async def update_snapshot( update_mask: Optional[field_mask_pb2.FieldMask] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Snapshot: r"""Updates an existing snapshot by updating the fields specified in the update mask. Snapshots are used in @@ -1959,8 +2017,10 @@ async def sample_update_snapshot(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Snapshot: @@ -2029,7 +2089,7 @@ async def delete_snapshot( snapshot: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> None: r"""Removes an existing snapshot. Snapshots are used in [Seek] (https://cloud.google.com/pubsub/docs/replay-overview) @@ -2078,8 +2138,10 @@ async def sample_delete_snapshot(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have @@ -2130,7 +2192,7 @@ async def seek( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.SeekResponse: r"""Seeks an existing subscription to a point in time or to a given snapshot, whichever is provided in the request. Snapshots are @@ -2174,8 +2236,10 @@ async def sample_seek(): retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.SeekResponse: @@ -2219,7 +2283,7 @@ async def set_iam_policy( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> policy_pb2.Policy: r"""Sets the IAM access control policy on the specified function. @@ -2232,8 +2296,10 @@ async def set_iam_policy( retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.policy_pb2.Policy: Defines an Identity and Access Management (IAM) policy. @@ -2337,7 +2403,7 @@ async def get_iam_policy( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> policy_pb2.Policy: r"""Gets the IAM access control policy for a function. @@ -2351,8 +2417,10 @@ async def get_iam_policy( retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.policy_pb2.Policy: Defines an Identity and Access Management (IAM) policy. @@ -2457,7 +2525,7 @@ async def test_iam_permissions( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> iam_policy_pb2.TestIamPermissionsResponse: r"""Tests the specified permissions against the IAM access control policy for a function. @@ -2472,8 +2540,10 @@ async def test_iam_permissions( retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~iam_policy_pb2.PolicyTestIamPermissionsResponse: Response message for ``TestIamPermissions`` method. diff --git a/google/pubsub_v1/services/subscriber/client.py b/google/pubsub_v1/services/subscriber/client.py index d601b0f0d..e248771e4 100644 --- a/google/pubsub_v1/services/subscriber/client.py +++ b/google/pubsub_v1/services/subscriber/client.py @@ -14,6 +14,9 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging import functools import os import re @@ -52,6 +55,15 @@ except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore from google.protobuf import duration_pb2 # type: ignore @@ -528,6 +540,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -632,6 +671,10 @@ def __init__( # Initialize the universe domain validation. self._is_universe_domain_valid = False + if CLIENT_LOGGING_SUPPORTED: # pragma: NO COVER + # Setup logging. + client_logging.initialize_logging() + api_key_value = getattr(self._client_options, "api_key", None) if api_key_value and credentials: raise ValueError( @@ -703,6 +746,29 @@ def __init__( api_audience=self._client_options.api_audience, ) + if "async" not in str(self._transport): + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.pubsub_v1.SubscriberClient`.", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "universeDomain": getattr( + self._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._transport._credentials).__module__}.{type(self._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._transport, "_credentials") + else { + "serviceName": "google.pubsub.v1.Subscriber", + "credentialsType": None, + }, + ) + def create_subscription( self, request: Optional[Union[pubsub.Subscription, dict]] = None, @@ -713,7 +779,7 @@ def create_subscription( ack_deadline_seconds: Optional[int] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Subscription: r"""Creates a subscription to a given topic. See the [resource name rules] @@ -826,8 +892,10 @@ def sample_create_subscription(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Subscription: @@ -893,7 +961,7 @@ def get_subscription( subscription: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Subscription: r"""Gets the configuration details of a subscription. @@ -937,8 +1005,10 @@ def sample_get_subscription(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Subscription: @@ -1001,7 +1071,7 @@ def update_subscription( update_mask: Optional[field_mask_pb2.FieldMask] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Subscription: r"""Updates an existing subscription by updating the fields specified in the update mask. Note that certain @@ -1060,8 +1130,10 @@ def sample_update_subscription(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Subscription: @@ -1125,7 +1197,7 @@ def list_subscriptions( project: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListSubscriptionsPager: r"""Lists matching subscriptions. @@ -1169,8 +1241,10 @@ def sample_list_subscriptions(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.services.subscriber.pagers.ListSubscriptionsPager: @@ -1241,7 +1315,7 @@ def delete_subscription( subscription: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> None: r"""Deletes an existing subscription. All messages retained in the subscription are immediately dropped. Calls to ``Pull`` after @@ -1287,8 +1361,10 @@ def sample_delete_subscription(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have @@ -1341,7 +1417,7 @@ def modify_ack_deadline( ack_deadline_seconds: Optional[int] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> None: r"""Modifies the ack deadline for a specific message. This method is useful to indicate that more time is needed to process a message @@ -1410,8 +1486,10 @@ def sample_modify_ack_deadline(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have @@ -1467,7 +1545,7 @@ def acknowledge( ack_ids: Optional[MutableSequence[str]] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> None: r"""Acknowledges the messages associated with the ``ack_ids`` in the ``AcknowledgeRequest``. The Pub/Sub system can remove the @@ -1524,8 +1602,10 @@ def sample_acknowledge(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have @@ -1580,7 +1660,7 @@ def pull( max_messages: Optional[int] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.PullResponse: r"""Pulls messages from the server. @@ -1649,8 +1729,10 @@ def sample_pull(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.PullResponse: @@ -1717,7 +1799,7 @@ def streaming_pull( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> Iterable[pubsub.StreamingPullResponse]: r"""Establishes a stream with the server, which sends messages down to the client. The client streams acknowledgements and ack @@ -1775,8 +1857,10 @@ def request_generator(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: Iterable[google.pubsub_v1.types.StreamingPullResponse]: @@ -1816,7 +1900,7 @@ def modify_push_config( push_config: Optional[pubsub.PushConfig] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> None: r"""Modifies the ``PushConfig`` for a specified subscription. @@ -1875,8 +1959,10 @@ def sample_modify_push_config(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have @@ -1929,7 +2015,7 @@ def get_snapshot( snapshot: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Snapshot: r"""Gets the configuration details of a snapshot. Snapshots are used in @@ -1977,8 +2063,10 @@ def sample_get_snapshot(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Snapshot: @@ -2040,7 +2128,7 @@ def list_snapshots( project: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListSnapshotsPager: r"""Lists the existing snapshots. Snapshots are used in `Seek `__ @@ -2088,8 +2176,10 @@ def sample_list_snapshots(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.services.subscriber.pagers.ListSnapshotsPager: @@ -2161,7 +2251,7 @@ def create_snapshot( subscription: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Snapshot: r"""Creates a snapshot from the requested subscription. Snapshots are used in @@ -2244,8 +2334,10 @@ def sample_create_snapshot(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Snapshot: @@ -2310,7 +2402,7 @@ def update_snapshot( update_mask: Optional[field_mask_pb2.FieldMask] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Snapshot: r"""Updates an existing snapshot by updating the fields specified in the update mask. Snapshots are used in @@ -2366,8 +2458,10 @@ def sample_update_snapshot(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.Snapshot: @@ -2433,7 +2527,7 @@ def delete_snapshot( snapshot: Optional[str] = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> None: r"""Removes an existing snapshot. Snapshots are used in [Seek] (https://cloud.google.com/pubsub/docs/replay-overview) @@ -2482,8 +2576,10 @@ def sample_delete_snapshot(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have @@ -2531,7 +2627,7 @@ def seek( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.SeekResponse: r"""Seeks an existing subscription to a point in time or to a given snapshot, whichever is provided in the request. Snapshots are @@ -2575,8 +2671,10 @@ def sample_seek(): retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: google.pubsub_v1.types.SeekResponse: @@ -2633,7 +2731,7 @@ def set_iam_policy( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> policy_pb2.Policy: r"""Sets the IAM access control policy on the specified function. @@ -2646,8 +2744,10 @@ def set_iam_policy( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.policy_pb2.Policy: Defines an Identity and Access Management (IAM) policy. @@ -2739,16 +2839,20 @@ def set_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_iam_policy( self, @@ -2756,7 +2860,7 @@ def get_iam_policy( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> policy_pb2.Policy: r"""Gets the IAM access control policy for a function. @@ -2770,8 +2874,10 @@ def get_iam_policy( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.policy_pb2.Policy: Defines an Identity and Access Management (IAM) policy. @@ -2863,16 +2969,20 @@ def get_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def test_iam_permissions( self, @@ -2880,7 +2990,7 @@ def test_iam_permissions( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> iam_policy_pb2.TestIamPermissionsResponse: r"""Tests the specified IAM permissions against the IAM access control policy for a function. @@ -2895,8 +3005,10 @@ def test_iam_permissions( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.iam_policy_pb2.TestIamPermissionsResponse: Response message for ``TestIamPermissions`` method. @@ -2925,16 +3037,20 @@ def test_iam_permissions( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/google/pubsub_v1/services/subscriber/pagers.py b/google/pubsub_v1/services/subscriber/pagers.py index c09c42027..26adcdd63 100644 --- a/google/pubsub_v1/services/subscriber/pagers.py +++ b/google/pubsub_v1/services/subscriber/pagers.py @@ -66,7 +66,7 @@ def __init__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = () + metadata: Sequence[Tuple[str, Union[str, bytes]]] = () ): """Instantiate the pager. @@ -80,8 +80,10 @@ def __init__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ self._method = method self._request = pubsub.ListSubscriptionsRequest(request) @@ -140,7 +142,7 @@ def __init__( *, retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = () + metadata: Sequence[Tuple[str, Union[str, bytes]]] = () ): """Instantiates the pager. @@ -154,8 +156,10 @@ def __init__( retry (google.api_core.retry.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ self._method = method self._request = pubsub.ListSubscriptionsRequest(request) @@ -218,7 +222,7 @@ def __init__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = () + metadata: Sequence[Tuple[str, Union[str, bytes]]] = () ): """Instantiate the pager. @@ -232,8 +236,10 @@ def __init__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ self._method = method self._request = pubsub.ListSnapshotsRequest(request) @@ -292,7 +298,7 @@ def __init__( *, retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = () + metadata: Sequence[Tuple[str, Union[str, bytes]]] = () ): """Instantiates the pager. @@ -306,8 +312,10 @@ def __init__( retry (google.api_core.retry.AsyncRetry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ self._method = method self._request = pubsub.ListSnapshotsRequest(request) diff --git a/google/pubsub_v1/services/subscriber/transports/grpc.py b/google/pubsub_v1/services/subscriber/transports/grpc.py index e706190ce..8282cf057 100644 --- a/google/pubsub_v1/services/subscriber/transports/grpc.py +++ b/google/pubsub_v1/services/subscriber/transports/grpc.py @@ -13,6 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import json +import logging as std_logging +import pickle import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union @@ -21,8 +24,11 @@ import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore +import proto # type: ignore from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore @@ -30,6 +36,81 @@ from google.pubsub_v1.types import pubsub from .base import SubscriberTransport, DEFAULT_CLIENT_INFO +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor(grpc.UnaryUnaryClientInterceptor): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": client_call_details.method, + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + + response = continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = response.result() + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response for {client_call_details.method}.", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class SubscriberGrpcTransport(SubscriberTransport): """gRPC backend transport for Subscriber. @@ -188,7 +269,12 @@ def __init__( ], ) - # Wrap messages. This must be done after self._grpc_channel exists + self._interceptor = _LoggingClientInterceptor() + self._logged_channel = grpc.intercept_channel( + self._grpc_channel, self._interceptor + ) + + # Wrap messages. This must be done after self._logged_channel exists self._prep_wrapped_messages(client_info) @classmethod @@ -274,7 +360,7 @@ def create_subscription( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_subscription" not in self._stubs: - self._stubs["create_subscription"] = self.grpc_channel.unary_unary( + self._stubs["create_subscription"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/CreateSubscription", request_serializer=pubsub.Subscription.serialize, response_deserializer=pubsub.Subscription.deserialize, @@ -300,7 +386,7 @@ def get_subscription( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_subscription" not in self._stubs: - self._stubs["get_subscription"] = self.grpc_channel.unary_unary( + self._stubs["get_subscription"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/GetSubscription", request_serializer=pubsub.GetSubscriptionRequest.serialize, response_deserializer=pubsub.Subscription.deserialize, @@ -329,7 +415,7 @@ def update_subscription( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_subscription" not in self._stubs: - self._stubs["update_subscription"] = self.grpc_channel.unary_unary( + self._stubs["update_subscription"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/UpdateSubscription", request_serializer=pubsub.UpdateSubscriptionRequest.serialize, response_deserializer=pubsub.Subscription.deserialize, @@ -355,7 +441,7 @@ def list_subscriptions( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_subscriptions" not in self._stubs: - self._stubs["list_subscriptions"] = self.grpc_channel.unary_unary( + self._stubs["list_subscriptions"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/ListSubscriptions", request_serializer=pubsub.ListSubscriptionsRequest.serialize, response_deserializer=pubsub.ListSubscriptionsResponse.deserialize, @@ -386,7 +472,7 @@ def delete_subscription( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_subscription" not in self._stubs: - self._stubs["delete_subscription"] = self.grpc_channel.unary_unary( + self._stubs["delete_subscription"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/DeleteSubscription", request_serializer=pubsub.DeleteSubscriptionRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -417,7 +503,7 @@ def modify_ack_deadline( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "modify_ack_deadline" not in self._stubs: - self._stubs["modify_ack_deadline"] = self.grpc_channel.unary_unary( + self._stubs["modify_ack_deadline"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/ModifyAckDeadline", request_serializer=pubsub.ModifyAckDeadlineRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -448,7 +534,7 @@ def acknowledge(self) -> Callable[[pubsub.AcknowledgeRequest], empty_pb2.Empty]: # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "acknowledge" not in self._stubs: - self._stubs["acknowledge"] = self.grpc_channel.unary_unary( + self._stubs["acknowledge"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/Acknowledge", request_serializer=pubsub.AcknowledgeRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -472,7 +558,7 @@ def pull(self) -> Callable[[pubsub.PullRequest], pubsub.PullResponse]: # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "pull" not in self._stubs: - self._stubs["pull"] = self.grpc_channel.unary_unary( + self._stubs["pull"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/Pull", request_serializer=pubsub.PullRequest.serialize, response_deserializer=pubsub.PullResponse.deserialize, @@ -505,7 +591,7 @@ def streaming_pull( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "streaming_pull" not in self._stubs: - self._stubs["streaming_pull"] = self.grpc_channel.stream_stream( + self._stubs["streaming_pull"] = self._logged_channel.stream_stream( "/google.pubsub.v1.Subscriber/StreamingPull", request_serializer=pubsub.StreamingPullRequest.serialize, response_deserializer=pubsub.StreamingPullResponse.deserialize, @@ -537,7 +623,7 @@ def modify_push_config( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "modify_push_config" not in self._stubs: - self._stubs["modify_push_config"] = self.grpc_channel.unary_unary( + self._stubs["modify_push_config"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/ModifyPushConfig", request_serializer=pubsub.ModifyPushConfigRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -566,7 +652,7 @@ def get_snapshot(self) -> Callable[[pubsub.GetSnapshotRequest], pubsub.Snapshot] # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_snapshot" not in self._stubs: - self._stubs["get_snapshot"] = self.grpc_channel.unary_unary( + self._stubs["get_snapshot"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/GetSnapshot", request_serializer=pubsub.GetSnapshotRequest.serialize, response_deserializer=pubsub.Snapshot.deserialize, @@ -596,7 +682,7 @@ def list_snapshots( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_snapshots" not in self._stubs: - self._stubs["list_snapshots"] = self.grpc_channel.unary_unary( + self._stubs["list_snapshots"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/ListSnapshots", request_serializer=pubsub.ListSnapshotsRequest.serialize, response_deserializer=pubsub.ListSnapshotsResponse.deserialize, @@ -640,7 +726,7 @@ def create_snapshot( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_snapshot" not in self._stubs: - self._stubs["create_snapshot"] = self.grpc_channel.unary_unary( + self._stubs["create_snapshot"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/CreateSnapshot", request_serializer=pubsub.CreateSnapshotRequest.serialize, response_deserializer=pubsub.Snapshot.deserialize, @@ -671,7 +757,7 @@ def update_snapshot( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_snapshot" not in self._stubs: - self._stubs["update_snapshot"] = self.grpc_channel.unary_unary( + self._stubs["update_snapshot"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/UpdateSnapshot", request_serializer=pubsub.UpdateSnapshotRequest.serialize, response_deserializer=pubsub.Snapshot.deserialize, @@ -706,7 +792,7 @@ def delete_snapshot( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_snapshot" not in self._stubs: - self._stubs["delete_snapshot"] = self.grpc_channel.unary_unary( + self._stubs["delete_snapshot"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/DeleteSnapshot", request_serializer=pubsub.DeleteSnapshotRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -738,7 +824,7 @@ def seek(self) -> Callable[[pubsub.SeekRequest], pubsub.SeekResponse]: # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "seek" not in self._stubs: - self._stubs["seek"] = self.grpc_channel.unary_unary( + self._stubs["seek"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/Seek", request_serializer=pubsub.SeekRequest.serialize, response_deserializer=pubsub.SeekResponse.deserialize, @@ -763,7 +849,7 @@ def set_iam_policy( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "set_iam_policy" not in self._stubs: - self._stubs["set_iam_policy"] = self.grpc_channel.unary_unary( + self._stubs["set_iam_policy"] = self._logged_channel.unary_unary( "/google.iam.v1.IAMPolicy/SetIamPolicy", request_serializer=iam_policy_pb2.SetIamPolicyRequest.SerializeToString, response_deserializer=policy_pb2.Policy.FromString, @@ -789,7 +875,7 @@ def get_iam_policy( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_iam_policy" not in self._stubs: - self._stubs["get_iam_policy"] = self.grpc_channel.unary_unary( + self._stubs["get_iam_policy"] = self._logged_channel.unary_unary( "/google.iam.v1.IAMPolicy/GetIamPolicy", request_serializer=iam_policy_pb2.GetIamPolicyRequest.SerializeToString, response_deserializer=policy_pb2.Policy.FromString, @@ -818,7 +904,7 @@ def test_iam_permissions( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "test_iam_permissions" not in self._stubs: - self._stubs["test_iam_permissions"] = self.grpc_channel.unary_unary( + self._stubs["test_iam_permissions"] = self._logged_channel.unary_unary( "/google.iam.v1.IAMPolicy/TestIamPermissions", request_serializer=iam_policy_pb2.TestIamPermissionsRequest.SerializeToString, response_deserializer=iam_policy_pb2.TestIamPermissionsResponse.FromString, @@ -826,7 +912,7 @@ def test_iam_permissions( return self._stubs["test_iam_permissions"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/google/pubsub_v1/services/subscriber/transports/grpc_asyncio.py b/google/pubsub_v1/services/subscriber/transports/grpc_asyncio.py index de9606858..6c4a97c9a 100644 --- a/google/pubsub_v1/services/subscriber/transports/grpc_asyncio.py +++ b/google/pubsub_v1/services/subscriber/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import pickle +import logging as std_logging import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union @@ -23,8 +26,11 @@ from google.api_core import retry_async as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore +import proto # type: ignore from grpc.experimental import aio # type: ignore from google.iam.v1 import iam_policy_pb2 # type: ignore @@ -34,6 +40,82 @@ from .base import SubscriberTransport, DEFAULT_CLIENT_INFO from .grpc import SubscriberGrpcTransport +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientAIOInterceptor( + grpc.aio.UnaryUnaryClientInterceptor +): # pragma: NO COVER + async def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": str(client_call_details.method), + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + response = await continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = await response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = await response + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response to rpc {client_call_details.method}.", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class SubscriberGrpcAsyncIOTransport(SubscriberTransport): """gRPC AsyncIO backend transport for Subscriber. @@ -235,10 +317,13 @@ def __init__( ], ) - # Wrap messages. This must be done after self._grpc_channel exists + self._interceptor = _LoggingClientAIOInterceptor() + self._grpc_channel._unary_unary_interceptors.append(self._interceptor) + self._logged_channel = self._grpc_channel self._wrap_with_kind = ( "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters ) + # Wrap messages. This must be done after self._logged_channel exists self._prep_wrapped_messages(client_info) @property @@ -282,7 +367,7 @@ def create_subscription( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_subscription" not in self._stubs: - self._stubs["create_subscription"] = self.grpc_channel.unary_unary( + self._stubs["create_subscription"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/CreateSubscription", request_serializer=pubsub.Subscription.serialize, response_deserializer=pubsub.Subscription.deserialize, @@ -308,7 +393,7 @@ def get_subscription( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_subscription" not in self._stubs: - self._stubs["get_subscription"] = self.grpc_channel.unary_unary( + self._stubs["get_subscription"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/GetSubscription", request_serializer=pubsub.GetSubscriptionRequest.serialize, response_deserializer=pubsub.Subscription.deserialize, @@ -337,7 +422,7 @@ def update_subscription( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_subscription" not in self._stubs: - self._stubs["update_subscription"] = self.grpc_channel.unary_unary( + self._stubs["update_subscription"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/UpdateSubscription", request_serializer=pubsub.UpdateSubscriptionRequest.serialize, response_deserializer=pubsub.Subscription.deserialize, @@ -365,7 +450,7 @@ def list_subscriptions( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_subscriptions" not in self._stubs: - self._stubs["list_subscriptions"] = self.grpc_channel.unary_unary( + self._stubs["list_subscriptions"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/ListSubscriptions", request_serializer=pubsub.ListSubscriptionsRequest.serialize, response_deserializer=pubsub.ListSubscriptionsResponse.deserialize, @@ -396,7 +481,7 @@ def delete_subscription( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_subscription" not in self._stubs: - self._stubs["delete_subscription"] = self.grpc_channel.unary_unary( + self._stubs["delete_subscription"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/DeleteSubscription", request_serializer=pubsub.DeleteSubscriptionRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -427,7 +512,7 @@ def modify_ack_deadline( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "modify_ack_deadline" not in self._stubs: - self._stubs["modify_ack_deadline"] = self.grpc_channel.unary_unary( + self._stubs["modify_ack_deadline"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/ModifyAckDeadline", request_serializer=pubsub.ModifyAckDeadlineRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -460,7 +545,7 @@ def acknowledge( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "acknowledge" not in self._stubs: - self._stubs["acknowledge"] = self.grpc_channel.unary_unary( + self._stubs["acknowledge"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/Acknowledge", request_serializer=pubsub.AcknowledgeRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -484,7 +569,7 @@ def pull(self) -> Callable[[pubsub.PullRequest], Awaitable[pubsub.PullResponse]] # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "pull" not in self._stubs: - self._stubs["pull"] = self.grpc_channel.unary_unary( + self._stubs["pull"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/Pull", request_serializer=pubsub.PullRequest.serialize, response_deserializer=pubsub.PullResponse.deserialize, @@ -519,7 +604,7 @@ def streaming_pull( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "streaming_pull" not in self._stubs: - self._stubs["streaming_pull"] = self.grpc_channel.stream_stream( + self._stubs["streaming_pull"] = self._logged_channel.stream_stream( "/google.pubsub.v1.Subscriber/StreamingPull", request_serializer=pubsub.StreamingPullRequest.serialize, response_deserializer=pubsub.StreamingPullResponse.deserialize, @@ -551,7 +636,7 @@ def modify_push_config( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "modify_push_config" not in self._stubs: - self._stubs["modify_push_config"] = self.grpc_channel.unary_unary( + self._stubs["modify_push_config"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/ModifyPushConfig", request_serializer=pubsub.ModifyPushConfigRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -582,7 +667,7 @@ def get_snapshot( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_snapshot" not in self._stubs: - self._stubs["get_snapshot"] = self.grpc_channel.unary_unary( + self._stubs["get_snapshot"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/GetSnapshot", request_serializer=pubsub.GetSnapshotRequest.serialize, response_deserializer=pubsub.Snapshot.deserialize, @@ -614,7 +699,7 @@ def list_snapshots( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_snapshots" not in self._stubs: - self._stubs["list_snapshots"] = self.grpc_channel.unary_unary( + self._stubs["list_snapshots"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/ListSnapshots", request_serializer=pubsub.ListSnapshotsRequest.serialize, response_deserializer=pubsub.ListSnapshotsResponse.deserialize, @@ -658,7 +743,7 @@ def create_snapshot( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_snapshot" not in self._stubs: - self._stubs["create_snapshot"] = self.grpc_channel.unary_unary( + self._stubs["create_snapshot"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/CreateSnapshot", request_serializer=pubsub.CreateSnapshotRequest.serialize, response_deserializer=pubsub.Snapshot.deserialize, @@ -689,7 +774,7 @@ def update_snapshot( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_snapshot" not in self._stubs: - self._stubs["update_snapshot"] = self.grpc_channel.unary_unary( + self._stubs["update_snapshot"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/UpdateSnapshot", request_serializer=pubsub.UpdateSnapshotRequest.serialize, response_deserializer=pubsub.Snapshot.deserialize, @@ -724,7 +809,7 @@ def delete_snapshot( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_snapshot" not in self._stubs: - self._stubs["delete_snapshot"] = self.grpc_channel.unary_unary( + self._stubs["delete_snapshot"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/DeleteSnapshot", request_serializer=pubsub.DeleteSnapshotRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -756,7 +841,7 @@ def seek(self) -> Callable[[pubsub.SeekRequest], Awaitable[pubsub.SeekResponse]] # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "seek" not in self._stubs: - self._stubs["seek"] = self.grpc_channel.unary_unary( + self._stubs["seek"] = self._logged_channel.unary_unary( "/google.pubsub.v1.Subscriber/Seek", request_serializer=pubsub.SeekRequest.serialize, response_deserializer=pubsub.SeekResponse.deserialize, @@ -781,7 +866,7 @@ def set_iam_policy( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "set_iam_policy" not in self._stubs: - self._stubs["set_iam_policy"] = self.grpc_channel.unary_unary( + self._stubs["set_iam_policy"] = self._logged_channel.unary_unary( "/google.iam.v1.IAMPolicy/SetIamPolicy", request_serializer=iam_policy_pb2.SetIamPolicyRequest.SerializeToString, response_deserializer=policy_pb2.Policy.FromString, @@ -807,7 +892,7 @@ def get_iam_policy( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_iam_policy" not in self._stubs: - self._stubs["get_iam_policy"] = self.grpc_channel.unary_unary( + self._stubs["get_iam_policy"] = self._logged_channel.unary_unary( "/google.iam.v1.IAMPolicy/GetIamPolicy", request_serializer=iam_policy_pb2.GetIamPolicyRequest.SerializeToString, response_deserializer=policy_pb2.Policy.FromString, @@ -836,7 +921,7 @@ def test_iam_permissions( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "test_iam_permissions" not in self._stubs: - self._stubs["test_iam_permissions"] = self.grpc_channel.unary_unary( + self._stubs["test_iam_permissions"] = self._logged_channel.unary_unary( "/google.iam.v1.IAMPolicy/TestIamPermissions", request_serializer=iam_policy_pb2.TestIamPermissionsRequest.SerializeToString, response_deserializer=iam_policy_pb2.TestIamPermissionsResponse.FromString, @@ -1112,7 +1197,7 @@ def _wrap_method(self, func, *args, **kwargs): return gapic_v1.method_async.wrap_method(func, *args, **kwargs) def close(self): - return self.grpc_channel.close() + return self._logged_channel.close() @property def kind(self) -> str: diff --git a/google/pubsub_v1/services/subscriber/transports/rest.py b/google/pubsub_v1/services/subscriber/transports/rest.py index 376fd4ab3..9d1fef9fc 100644 --- a/google/pubsub_v1/services/subscriber/transports/rest.py +++ b/google/pubsub_v1/services/subscriber/transports/rest.py @@ -13,9 +13,10 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import logging +import json # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore -import json # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries @@ -47,6 +48,14 @@ except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = logging.getLogger(__name__) DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, @@ -177,8 +186,10 @@ def post_update_subscription(self, response): """ def pre_acknowledge( - self, request: pubsub.AcknowledgeRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[pubsub.AcknowledgeRequest, Sequence[Tuple[str, str]]]: + self, + request: pubsub.AcknowledgeRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.AcknowledgeRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for acknowledge Override in a subclass to manipulate the request or metadata @@ -187,8 +198,10 @@ def pre_acknowledge( return request, metadata def pre_create_snapshot( - self, request: pubsub.CreateSnapshotRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[pubsub.CreateSnapshotRequest, Sequence[Tuple[str, str]]]: + self, + request: pubsub.CreateSnapshotRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.CreateSnapshotRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for create_snapshot Override in a subclass to manipulate the request or metadata @@ -199,15 +212,40 @@ def pre_create_snapshot( def post_create_snapshot(self, response: pubsub.Snapshot) -> pubsub.Snapshot: """Post-rpc interceptor for create_snapshot - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_snapshot_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Subscriber server but before - it is returned to user code. + it is returned to user code. This `post_create_snapshot` interceptor runs + before the `post_create_snapshot_with_metadata` interceptor. """ return response + def post_create_snapshot_with_metadata( + self, + response: pubsub.Snapshot, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.Snapshot, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_snapshot + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Subscriber server but before it is returned to user code. + + We recommend only using this `post_create_snapshot_with_metadata` + interceptor in new development instead of the `post_create_snapshot` interceptor. + When both interceptors are used, this `post_create_snapshot_with_metadata` interceptor runs after the + `post_create_snapshot` interceptor. The (possibly modified) response returned by + `post_create_snapshot` will be passed to + `post_create_snapshot_with_metadata`. + """ + return response, metadata + def pre_create_subscription( - self, request: pubsub.Subscription, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[pubsub.Subscription, Sequence[Tuple[str, str]]]: + self, + request: pubsub.Subscription, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.Subscription, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for create_subscription Override in a subclass to manipulate the request or metadata @@ -220,15 +258,40 @@ def post_create_subscription( ) -> pubsub.Subscription: """Post-rpc interceptor for create_subscription - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_subscription_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Subscriber server but before - it is returned to user code. + it is returned to user code. This `post_create_subscription` interceptor runs + before the `post_create_subscription_with_metadata` interceptor. """ return response + def post_create_subscription_with_metadata( + self, + response: pubsub.Subscription, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.Subscription, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_subscription + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Subscriber server but before it is returned to user code. + + We recommend only using this `post_create_subscription_with_metadata` + interceptor in new development instead of the `post_create_subscription` interceptor. + When both interceptors are used, this `post_create_subscription_with_metadata` interceptor runs after the + `post_create_subscription` interceptor. The (possibly modified) response returned by + `post_create_subscription` will be passed to + `post_create_subscription_with_metadata`. + """ + return response, metadata + def pre_delete_snapshot( - self, request: pubsub.DeleteSnapshotRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[pubsub.DeleteSnapshotRequest, Sequence[Tuple[str, str]]]: + self, + request: pubsub.DeleteSnapshotRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.DeleteSnapshotRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for delete_snapshot Override in a subclass to manipulate the request or metadata @@ -239,8 +302,10 @@ def pre_delete_snapshot( def pre_delete_subscription( self, request: pubsub.DeleteSubscriptionRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[pubsub.DeleteSubscriptionRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + pubsub.DeleteSubscriptionRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for delete_subscription Override in a subclass to manipulate the request or metadata @@ -249,8 +314,10 @@ def pre_delete_subscription( return request, metadata def pre_get_snapshot( - self, request: pubsub.GetSnapshotRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[pubsub.GetSnapshotRequest, Sequence[Tuple[str, str]]]: + self, + request: pubsub.GetSnapshotRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.GetSnapshotRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for get_snapshot Override in a subclass to manipulate the request or metadata @@ -261,17 +328,40 @@ def pre_get_snapshot( def post_get_snapshot(self, response: pubsub.Snapshot) -> pubsub.Snapshot: """Post-rpc interceptor for get_snapshot - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_snapshot_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Subscriber server but before - it is returned to user code. + it is returned to user code. This `post_get_snapshot` interceptor runs + before the `post_get_snapshot_with_metadata` interceptor. """ return response + def post_get_snapshot_with_metadata( + self, + response: pubsub.Snapshot, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.Snapshot, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_snapshot + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Subscriber server but before it is returned to user code. + + We recommend only using this `post_get_snapshot_with_metadata` + interceptor in new development instead of the `post_get_snapshot` interceptor. + When both interceptors are used, this `post_get_snapshot_with_metadata` interceptor runs after the + `post_get_snapshot` interceptor. The (possibly modified) response returned by + `post_get_snapshot` will be passed to + `post_get_snapshot_with_metadata`. + """ + return response, metadata + def pre_get_subscription( self, request: pubsub.GetSubscriptionRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[pubsub.GetSubscriptionRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.GetSubscriptionRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for get_subscription Override in a subclass to manipulate the request or metadata @@ -284,15 +374,40 @@ def post_get_subscription( ) -> pubsub.Subscription: """Post-rpc interceptor for get_subscription - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_subscription_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Subscriber server but before - it is returned to user code. + it is returned to user code. This `post_get_subscription` interceptor runs + before the `post_get_subscription_with_metadata` interceptor. """ return response + def post_get_subscription_with_metadata( + self, + response: pubsub.Subscription, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.Subscription, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_subscription + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Subscriber server but before it is returned to user code. + + We recommend only using this `post_get_subscription_with_metadata` + interceptor in new development instead of the `post_get_subscription` interceptor. + When both interceptors are used, this `post_get_subscription_with_metadata` interceptor runs after the + `post_get_subscription` interceptor. The (possibly modified) response returned by + `post_get_subscription` will be passed to + `post_get_subscription_with_metadata`. + """ + return response, metadata + def pre_list_snapshots( - self, request: pubsub.ListSnapshotsRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[pubsub.ListSnapshotsRequest, Sequence[Tuple[str, str]]]: + self, + request: pubsub.ListSnapshotsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.ListSnapshotsRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for list_snapshots Override in a subclass to manipulate the request or metadata @@ -305,17 +420,42 @@ def post_list_snapshots( ) -> pubsub.ListSnapshotsResponse: """Post-rpc interceptor for list_snapshots - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_snapshots_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Subscriber server but before - it is returned to user code. + it is returned to user code. This `post_list_snapshots` interceptor runs + before the `post_list_snapshots_with_metadata` interceptor. """ return response + def post_list_snapshots_with_metadata( + self, + response: pubsub.ListSnapshotsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.ListSnapshotsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_snapshots + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Subscriber server but before it is returned to user code. + + We recommend only using this `post_list_snapshots_with_metadata` + interceptor in new development instead of the `post_list_snapshots` interceptor. + When both interceptors are used, this `post_list_snapshots_with_metadata` interceptor runs after the + `post_list_snapshots` interceptor. The (possibly modified) response returned by + `post_list_snapshots` will be passed to + `post_list_snapshots_with_metadata`. + """ + return response, metadata + def pre_list_subscriptions( self, request: pubsub.ListSubscriptionsRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[pubsub.ListSubscriptionsRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + pubsub.ListSubscriptionsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for list_subscriptions Override in a subclass to manipulate the request or metadata @@ -328,17 +468,44 @@ def post_list_subscriptions( ) -> pubsub.ListSubscriptionsResponse: """Post-rpc interceptor for list_subscriptions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_subscriptions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Subscriber server but before - it is returned to user code. + it is returned to user code. This `post_list_subscriptions` interceptor runs + before the `post_list_subscriptions_with_metadata` interceptor. """ return response + def post_list_subscriptions_with_metadata( + self, + response: pubsub.ListSubscriptionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + pubsub.ListSubscriptionsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_subscriptions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Subscriber server but before it is returned to user code. + + We recommend only using this `post_list_subscriptions_with_metadata` + interceptor in new development instead of the `post_list_subscriptions` interceptor. + When both interceptors are used, this `post_list_subscriptions_with_metadata` interceptor runs after the + `post_list_subscriptions` interceptor. The (possibly modified) response returned by + `post_list_subscriptions` will be passed to + `post_list_subscriptions_with_metadata`. + """ + return response, metadata + def pre_modify_ack_deadline( self, request: pubsub.ModifyAckDeadlineRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[pubsub.ModifyAckDeadlineRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + pubsub.ModifyAckDeadlineRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for modify_ack_deadline Override in a subclass to manipulate the request or metadata @@ -349,8 +516,8 @@ def pre_modify_ack_deadline( def pre_modify_push_config( self, request: pubsub.ModifyPushConfigRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[pubsub.ModifyPushConfigRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.ModifyPushConfigRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for modify_push_config Override in a subclass to manipulate the request or metadata @@ -359,8 +526,10 @@ def pre_modify_push_config( return request, metadata def pre_pull( - self, request: pubsub.PullRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[pubsub.PullRequest, Sequence[Tuple[str, str]]]: + self, + request: pubsub.PullRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.PullRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for pull Override in a subclass to manipulate the request or metadata @@ -371,15 +540,40 @@ def pre_pull( def post_pull(self, response: pubsub.PullResponse) -> pubsub.PullResponse: """Post-rpc interceptor for pull - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_pull_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Subscriber server but before - it is returned to user code. + it is returned to user code. This `post_pull` interceptor runs + before the `post_pull_with_metadata` interceptor. """ return response + def post_pull_with_metadata( + self, + response: pubsub.PullResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.PullResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for pull + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Subscriber server but before it is returned to user code. + + We recommend only using this `post_pull_with_metadata` + interceptor in new development instead of the `post_pull` interceptor. + When both interceptors are used, this `post_pull_with_metadata` interceptor runs after the + `post_pull` interceptor. The (possibly modified) response returned by + `post_pull` will be passed to + `post_pull_with_metadata`. + """ + return response, metadata + def pre_seek( - self, request: pubsub.SeekRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[pubsub.SeekRequest, Sequence[Tuple[str, str]]]: + self, + request: pubsub.SeekRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.SeekRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for seek Override in a subclass to manipulate the request or metadata @@ -390,15 +584,40 @@ def pre_seek( def post_seek(self, response: pubsub.SeekResponse) -> pubsub.SeekResponse: """Post-rpc interceptor for seek - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_seek_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Subscriber server but before - it is returned to user code. + it is returned to user code. This `post_seek` interceptor runs + before the `post_seek_with_metadata` interceptor. """ return response + def post_seek_with_metadata( + self, + response: pubsub.SeekResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.SeekResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for seek + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Subscriber server but before it is returned to user code. + + We recommend only using this `post_seek_with_metadata` + interceptor in new development instead of the `post_seek` interceptor. + When both interceptors are used, this `post_seek_with_metadata` interceptor runs after the + `post_seek` interceptor. The (possibly modified) response returned by + `post_seek` will be passed to + `post_seek_with_metadata`. + """ + return response, metadata + def pre_update_snapshot( - self, request: pubsub.UpdateSnapshotRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[pubsub.UpdateSnapshotRequest, Sequence[Tuple[str, str]]]: + self, + request: pubsub.UpdateSnapshotRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.UpdateSnapshotRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for update_snapshot Override in a subclass to manipulate the request or metadata @@ -409,17 +628,42 @@ def pre_update_snapshot( def post_update_snapshot(self, response: pubsub.Snapshot) -> pubsub.Snapshot: """Post-rpc interceptor for update_snapshot - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_snapshot_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Subscriber server but before - it is returned to user code. + it is returned to user code. This `post_update_snapshot` interceptor runs + before the `post_update_snapshot_with_metadata` interceptor. """ return response + def post_update_snapshot_with_metadata( + self, + response: pubsub.Snapshot, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.Snapshot, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_snapshot + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Subscriber server but before it is returned to user code. + + We recommend only using this `post_update_snapshot_with_metadata` + interceptor in new development instead of the `post_update_snapshot` interceptor. + When both interceptors are used, this `post_update_snapshot_with_metadata` interceptor runs after the + `post_update_snapshot` interceptor. The (possibly modified) response returned by + `post_update_snapshot` will be passed to + `post_update_snapshot_with_metadata`. + """ + return response, metadata + def pre_update_subscription( self, request: pubsub.UpdateSubscriptionRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[pubsub.UpdateSubscriptionRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + pubsub.UpdateSubscriptionRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for update_subscription Override in a subclass to manipulate the request or metadata @@ -432,17 +676,42 @@ def post_update_subscription( ) -> pubsub.Subscription: """Post-rpc interceptor for update_subscription - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_subscription_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Subscriber server but before - it is returned to user code. + it is returned to user code. This `post_update_subscription` interceptor runs + before the `post_update_subscription_with_metadata` interceptor. """ return response + def post_update_subscription_with_metadata( + self, + response: pubsub.Subscription, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[pubsub.Subscription, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_subscription + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Subscriber server but before it is returned to user code. + + We recommend only using this `post_update_subscription_with_metadata` + interceptor in new development instead of the `post_update_subscription` interceptor. + When both interceptors are used, this `post_update_subscription_with_metadata` interceptor runs after the + `post_update_subscription` interceptor. The (possibly modified) response returned by + `post_update_subscription` will be passed to + `post_update_subscription_with_metadata`. + """ + return response, metadata + def pre_get_iam_policy( self, request: iam_policy_pb2.GetIamPolicyRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[iam_policy_pb2.GetIamPolicyRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + iam_policy_pb2.GetIamPolicyRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for get_iam_policy Override in a subclass to manipulate the request or metadata @@ -462,8 +731,10 @@ def post_get_iam_policy(self, response: policy_pb2.Policy) -> policy_pb2.Policy: def pre_set_iam_policy( self, request: iam_policy_pb2.SetIamPolicyRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[iam_policy_pb2.SetIamPolicyRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + iam_policy_pb2.SetIamPolicyRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for set_iam_policy Override in a subclass to manipulate the request or metadata @@ -483,8 +754,11 @@ def post_set_iam_policy(self, response: policy_pb2.Policy) -> policy_pb2.Policy: def pre_test_iam_permissions( self, request: iam_policy_pb2.TestIamPermissionsRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[iam_policy_pb2.TestIamPermissionsRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + iam_policy_pb2.TestIamPermissionsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: """Pre-rpc interceptor for test_iam_permissions Override in a subclass to manipulate the request or metadata @@ -628,7 +902,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ): r"""Call the acknowledge method over HTTP. @@ -638,13 +912,16 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ http_options = ( _BaseSubscriberRestTransport._BaseAcknowledge._get_http_options() ) + request, metadata = self._interceptor.pre_acknowledge(request, metadata) transcoded_request = ( _BaseSubscriberRestTransport._BaseAcknowledge._get_transcoded_request( @@ -663,6 +940,33 @@ def __call__( ) ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SubscriberClient.Acknowledge", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "Acknowledge", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SubscriberRestTransport._Acknowledge._get_response( self._host, @@ -714,7 +1018,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Snapshot: r"""Call the create snapshot method over HTTP. @@ -724,8 +1028,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.pubsub.Snapshot: @@ -741,6 +1047,7 @@ def __call__( http_options = ( _BaseSubscriberRestTransport._BaseCreateSnapshot._get_http_options() ) + request, metadata = self._interceptor.pre_create_snapshot(request, metadata) transcoded_request = _BaseSubscriberRestTransport._BaseCreateSnapshot._get_transcoded_request( http_options, request @@ -759,6 +1066,33 @@ def __call__( ) ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SubscriberClient.CreateSnapshot", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "CreateSnapshot", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SubscriberRestTransport._CreateSnapshot._get_response( self._host, @@ -780,7 +1114,33 @@ def __call__( pb_resp = pubsub.Snapshot.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_snapshot(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_snapshot_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = pubsub.Snapshot.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SubscriberClient.create_snapshot", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "CreateSnapshot", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _CreateSubscription( @@ -818,7 +1178,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Subscription: r"""Call the create subscription method over HTTP. @@ -831,8 +1191,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.pubsub.Subscription: @@ -846,6 +1208,7 @@ def __call__( http_options = ( _BaseSubscriberRestTransport._BaseCreateSubscription._get_http_options() ) + request, metadata = self._interceptor.pre_create_subscription( request, metadata ) @@ -862,6 +1225,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SubscriberClient.CreateSubscription", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "CreateSubscription", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SubscriberRestTransport._CreateSubscription._get_response( self._host, @@ -883,7 +1273,33 @@ def __call__( pb_resp = pubsub.Subscription.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_subscription(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_subscription_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = pubsub.Subscription.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SubscriberClient.create_subscription", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "CreateSubscription", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _DeleteSnapshot( @@ -920,7 +1336,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ): r"""Call the delete snapshot method over HTTP. @@ -930,13 +1346,16 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ http_options = ( _BaseSubscriberRestTransport._BaseDeleteSnapshot._get_http_options() ) + request, metadata = self._interceptor.pre_delete_snapshot(request, metadata) transcoded_request = _BaseSubscriberRestTransport._BaseDeleteSnapshot._get_transcoded_request( http_options, request @@ -949,6 +1368,33 @@ def __call__( ) ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SubscriberClient.DeleteSnapshot", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "DeleteSnapshot", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SubscriberRestTransport._DeleteSnapshot._get_response( self._host, @@ -998,7 +1444,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ): r"""Call the delete subscription method over HTTP. @@ -1009,13 +1455,16 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ http_options = ( _BaseSubscriberRestTransport._BaseDeleteSubscription._get_http_options() ) + request, metadata = self._interceptor.pre_delete_subscription( request, metadata ) @@ -1028,6 +1477,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SubscriberClient.DeleteSubscription", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "DeleteSubscription", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SubscriberRestTransport._DeleteSubscription._get_response( self._host, @@ -1077,7 +1553,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Snapshot: r"""Call the get snapshot method over HTTP. @@ -1087,8 +1563,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.pubsub.Snapshot: @@ -1104,6 +1582,7 @@ def __call__( http_options = ( _BaseSubscriberRestTransport._BaseGetSnapshot._get_http_options() ) + request, metadata = self._interceptor.pre_get_snapshot(request, metadata) transcoded_request = ( _BaseSubscriberRestTransport._BaseGetSnapshot._get_transcoded_request( @@ -1118,6 +1597,33 @@ def __call__( ) ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SubscriberClient.GetSnapshot", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "GetSnapshot", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SubscriberRestTransport._GetSnapshot._get_response( self._host, @@ -1138,7 +1644,33 @@ def __call__( pb_resp = pubsub.Snapshot.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_snapshot(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_snapshot_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = pubsub.Snapshot.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SubscriberClient.get_snapshot", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "GetSnapshot", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _GetSubscription( @@ -1175,7 +1707,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Subscription: r"""Call the get subscription method over HTTP. @@ -1186,8 +1718,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.pubsub.Subscription: @@ -1201,6 +1735,7 @@ def __call__( http_options = ( _BaseSubscriberRestTransport._BaseGetSubscription._get_http_options() ) + request, metadata = self._interceptor.pre_get_subscription( request, metadata ) @@ -1213,6 +1748,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SubscriberClient.GetSubscription", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "GetSubscription", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SubscriberRestTransport._GetSubscription._get_response( self._host, @@ -1233,7 +1795,33 @@ def __call__( pb_resp = pubsub.Subscription.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_subscription(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_subscription_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = pubsub.Subscription.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SubscriberClient.get_subscription", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "GetSubscription", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListSnapshots( @@ -1270,7 +1858,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.ListSnapshotsResponse: r"""Call the list snapshots method over HTTP. @@ -1280,8 +1868,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.pubsub.ListSnapshotsResponse: @@ -1291,6 +1881,7 @@ def __call__( http_options = ( _BaseSubscriberRestTransport._BaseListSnapshots._get_http_options() ) + request, metadata = self._interceptor.pre_list_snapshots(request, metadata) transcoded_request = ( _BaseSubscriberRestTransport._BaseListSnapshots._get_transcoded_request( @@ -1305,6 +1896,33 @@ def __call__( ) ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SubscriberClient.ListSnapshots", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "ListSnapshots", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SubscriberRestTransport._ListSnapshots._get_response( self._host, @@ -1325,7 +1943,33 @@ def __call__( pb_resp = pubsub.ListSnapshotsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_snapshots(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_snapshots_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = pubsub.ListSnapshotsResponse.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SubscriberClient.list_snapshots", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "ListSnapshots", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListSubscriptions( @@ -1362,7 +2006,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.ListSubscriptionsResponse: r"""Call the list subscriptions method over HTTP. @@ -1372,8 +2016,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.pubsub.ListSubscriptionsResponse: @@ -1383,6 +2029,7 @@ def __call__( http_options = ( _BaseSubscriberRestTransport._BaseListSubscriptions._get_http_options() ) + request, metadata = self._interceptor.pre_list_subscriptions( request, metadata ) @@ -1395,6 +2042,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SubscriberClient.ListSubscriptions", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "ListSubscriptions", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SubscriberRestTransport._ListSubscriptions._get_response( self._host, @@ -1415,7 +2089,35 @@ def __call__( pb_resp = pubsub.ListSubscriptionsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_subscriptions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_subscriptions_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = pubsub.ListSubscriptionsResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SubscriberClient.list_subscriptions", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "ListSubscriptions", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ModifyAckDeadline( @@ -1453,7 +2155,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ): r"""Call the modify ack deadline method over HTTP. @@ -1464,13 +2166,16 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ http_options = ( _BaseSubscriberRestTransport._BaseModifyAckDeadline._get_http_options() ) + request, metadata = self._interceptor.pre_modify_ack_deadline( request, metadata ) @@ -1487,6 +2192,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SubscriberClient.ModifyAckDeadline", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "ModifyAckDeadline", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SubscriberRestTransport._ModifyAckDeadline._get_response( self._host, @@ -1538,7 +2270,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ): r"""Call the modify push config method over HTTP. @@ -1549,13 +2281,16 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. """ http_options = ( _BaseSubscriberRestTransport._BaseModifyPushConfig._get_http_options() ) + request, metadata = self._interceptor.pre_modify_push_config( request, metadata ) @@ -1572,6 +2307,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SubscriberClient.ModifyPushConfig", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "ModifyPushConfig", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SubscriberRestTransport._ModifyPushConfig._get_response( self._host, @@ -1621,7 +2383,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.PullResponse: r"""Call the pull method over HTTP. @@ -1631,8 +2393,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.pubsub.PullResponse: @@ -1640,6 +2404,7 @@ def __call__( """ http_options = _BaseSubscriberRestTransport._BasePull._get_http_options() + request, metadata = self._interceptor.pre_pull(request, metadata) transcoded_request = ( _BaseSubscriberRestTransport._BasePull._get_transcoded_request( @@ -1658,6 +2423,33 @@ def __call__( ) ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SubscriberClient.Pull", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "Pull", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SubscriberRestTransport._Pull._get_response( self._host, @@ -1679,7 +2471,31 @@ def __call__( pb_resp = pubsub.PullResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_pull(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_pull_with_metadata(resp, response_metadata) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = pubsub.PullResponse.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SubscriberClient.pull", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "Pull", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _Seek(_BaseSubscriberRestTransport._BaseSeek, SubscriberRestStub): @@ -1715,7 +2531,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.SeekResponse: r"""Call the seek method over HTTP. @@ -1725,8 +2541,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.pubsub.SeekResponse: @@ -1736,6 +2554,7 @@ def __call__( """ http_options = _BaseSubscriberRestTransport._BaseSeek._get_http_options() + request, metadata = self._interceptor.pre_seek(request, metadata) transcoded_request = ( _BaseSubscriberRestTransport._BaseSeek._get_transcoded_request( @@ -1754,6 +2573,33 @@ def __call__( ) ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SubscriberClient.Seek", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "Seek", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SubscriberRestTransport._Seek._get_response( self._host, @@ -1775,7 +2621,31 @@ def __call__( pb_resp = pubsub.SeekResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_seek(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_seek_with_metadata(resp, response_metadata) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = pubsub.SeekResponse.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SubscriberClient.seek", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "Seek", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _StreamingPull( @@ -1790,7 +2660,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> rest_streaming.ResponseIterator: raise NotImplementedError( "Method StreamingPull is not available over REST transport" @@ -1831,7 +2701,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Snapshot: r"""Call the update snapshot method over HTTP. @@ -1842,8 +2712,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.pubsub.Snapshot: @@ -1859,6 +2731,7 @@ def __call__( http_options = ( _BaseSubscriberRestTransport._BaseUpdateSnapshot._get_http_options() ) + request, metadata = self._interceptor.pre_update_snapshot(request, metadata) transcoded_request = _BaseSubscriberRestTransport._BaseUpdateSnapshot._get_transcoded_request( http_options, request @@ -1877,6 +2750,33 @@ def __call__( ) ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SubscriberClient.UpdateSnapshot", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "UpdateSnapshot", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SubscriberRestTransport._UpdateSnapshot._get_response( self._host, @@ -1898,7 +2798,33 @@ def __call__( pb_resp = pubsub.Snapshot.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_snapshot(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_snapshot_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = pubsub.Snapshot.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SubscriberClient.update_snapshot", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "UpdateSnapshot", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _UpdateSubscription( @@ -1936,7 +2862,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pubsub.Subscription: r"""Call the update subscription method over HTTP. @@ -1947,8 +2873,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: ~.pubsub.Subscription: @@ -1962,6 +2890,7 @@ def __call__( http_options = ( _BaseSubscriberRestTransport._BaseUpdateSubscription._get_http_options() ) + request, metadata = self._interceptor.pre_update_subscription( request, metadata ) @@ -1978,6 +2907,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SubscriberClient.UpdateSubscription", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "UpdateSubscription", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SubscriberRestTransport._UpdateSubscription._get_response( self._host, @@ -1999,7 +2955,33 @@ def __call__( pb_resp = pubsub.Subscription.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_subscription(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_subscription_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = pubsub.Subscription.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SubscriberClient.update_subscription", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "UpdateSubscription", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property @@ -2160,7 +3142,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> policy_pb2.Policy: r"""Call the get iam policy method over HTTP. @@ -2170,8 +3152,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: policy_pb2.Policy: Response from GetIamPolicy method. @@ -2180,6 +3164,7 @@ def __call__( http_options = ( _BaseSubscriberRestTransport._BaseGetIamPolicy._get_http_options() ) + request, metadata = self._interceptor.pre_get_iam_policy(request, metadata) transcoded_request = ( _BaseSubscriberRestTransport._BaseGetIamPolicy._get_transcoded_request( @@ -2194,6 +3179,33 @@ def __call__( ) ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SubscriberClient.GetIamPolicy", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "GetIamPolicy", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SubscriberRestTransport._GetIamPolicy._get_response( self._host, @@ -2213,6 +3225,27 @@ def __call__( resp = policy_pb2.Policy() resp = json_format.Parse(content, resp) resp = self._interceptor.post_get_iam_policy(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SubscriberAsyncClient.GetIamPolicy", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "GetIamPolicy", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) return resp @property @@ -2254,7 +3287,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> policy_pb2.Policy: r"""Call the set iam policy method over HTTP. @@ -2264,8 +3297,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: policy_pb2.Policy: Response from SetIamPolicy method. @@ -2274,6 +3309,7 @@ def __call__( http_options = ( _BaseSubscriberRestTransport._BaseSetIamPolicy._get_http_options() ) + request, metadata = self._interceptor.pre_set_iam_policy(request, metadata) transcoded_request = ( _BaseSubscriberRestTransport._BaseSetIamPolicy._get_transcoded_request( @@ -2294,6 +3330,33 @@ def __call__( ) ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SubscriberClient.SetIamPolicy", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "SetIamPolicy", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SubscriberRestTransport._SetIamPolicy._get_response( self._host, @@ -2314,6 +3377,27 @@ def __call__( resp = policy_pb2.Policy() resp = json_format.Parse(content, resp) resp = self._interceptor.post_set_iam_policy(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SubscriberAsyncClient.SetIamPolicy", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "SetIamPolicy", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) return resp @property @@ -2355,7 +3439,7 @@ def __call__( *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> iam_policy_pb2.TestIamPermissionsResponse: r"""Call the test iam permissions method over HTTP. @@ -2365,8 +3449,10 @@ def __call__( retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. Returns: iam_policy_pb2.TestIamPermissionsResponse: Response from TestIamPermissions method. @@ -2375,6 +3461,7 @@ def __call__( http_options = ( _BaseSubscriberRestTransport._BaseTestIamPermissions._get_http_options() ) + request, metadata = self._interceptor.pre_test_iam_permissions( request, metadata ) @@ -2391,6 +3478,33 @@ def __call__( transcoded_request ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.pubsub_v1.SubscriberClient.TestIamPermissions", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "TestIamPermissions", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SubscriberRestTransport._TestIamPermissions._get_response( self._host, @@ -2411,6 +3525,27 @@ def __call__( resp = iam_policy_pb2.TestIamPermissionsResponse() resp = json_format.Parse(content, resp) resp = self._interceptor.post_test_iam_permissions(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.pubsub_v1.SubscriberAsyncClient.TestIamPermissions", + extra={ + "serviceName": "google.pubsub.v1.Subscriber", + "rpcName": "TestIamPermissions", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) return resp @property diff --git a/google/pubsub_v1/types/pubsub.py b/google/pubsub_v1/types/pubsub.py index 5f15e445b..96b1b71e9 100644 --- a/google/pubsub_v1/types/pubsub.py +++ b/google/pubsub_v1/types/pubsub.py @@ -1099,35 +1099,33 @@ class JavaScriptUDF(proto.Message): Required. JavaScript code that contains a function ``function_name`` with the below signature: - :: - // /** - // * Transforms a Pub/Sub message. - // - // * @return {(Object)>|null)} - To - // * filter a message, return `null`. To transform a message return a map - // * with the following keys: - // * - (required) 'data' : {string} - // * - (optional) 'attributes' : {Object} - // * Returning empty `attributes` will remove all attributes from the - // * message. - // * - // * @param {(Object)>} Pub/Sub - // * message. Keys: - // * - (required) 'data' : {string} - // * - (required) 'attributes' : {Object} - // * - // * @param {Object} metadata - Pub/Sub message metadata. - // * Keys: - // * - (required) 'message_id' : {string} - // * - (optional) 'publish_time': {string} YYYY-MM-DDTHH:MM:SSZ format - // * - (optional) 'ordering_key': {string} - // */ - // - // function (message, metadata) { - // } - + /** + * Transforms a Pub/Sub message. + + * @return {(Object)>|null)} - To + * filter a message, return `null`. To transform a message return a map + * with the following keys: + * - (required) 'data' : {string} + * - (optional) 'attributes' : {Object} + * Returning empty `attributes` will remove all attributes from the + * message. + * + * @param {(Object)>} Pub/Sub + * message. Keys: + * - (required) 'data' : {string} + * - (required) 'attributes' : {Object} + * + * @param {Object} metadata - Pub/Sub message metadata. + * Keys: + * - (required) 'message_id' : {string} + * - (optional) 'publish_time': {string} YYYY-MM-DDTHH:MM:SSZ format + * - (optional) 'ordering_key': {string} + */ + + function (message, metadata) { + } """ function_name: str = proto.Field( diff --git a/samples/generated_samples/snippet_metadata_google.pubsub.v1.json b/samples/generated_samples/snippet_metadata_google.pubsub.v1.json index 039f0ca3d..dd0d6423a 100644 --- a/samples/generated_samples/snippet_metadata_google.pubsub.v1.json +++ b/samples/generated_samples/snippet_metadata_google.pubsub.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-pubsub", - "version": "2.28.0" + "version": "0.1.0" }, "snippets": [ { @@ -47,7 +47,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Topic", @@ -127,7 +127,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Topic", @@ -208,7 +208,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_topic" @@ -285,7 +285,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_topic" @@ -359,7 +359,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.DetachSubscriptionResponse", @@ -435,7 +435,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.DetachSubscriptionResponse", @@ -516,7 +516,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Topic", @@ -596,7 +596,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Topic", @@ -677,7 +677,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.services.publisher.pagers.ListTopicSnapshotsAsyncPager", @@ -757,7 +757,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.services.publisher.pagers.ListTopicSnapshotsPager", @@ -838,7 +838,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.services.publisher.pagers.ListTopicSubscriptionsAsyncPager", @@ -918,7 +918,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.services.publisher.pagers.ListTopicSubscriptionsPager", @@ -999,7 +999,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.services.publisher.pagers.ListTopicsAsyncPager", @@ -1079,7 +1079,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.services.publisher.pagers.ListTopicsPager", @@ -1164,7 +1164,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.PublishResponse", @@ -1248,7 +1248,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.PublishResponse", @@ -1333,7 +1333,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Topic", @@ -1417,7 +1417,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Topic", @@ -1502,7 +1502,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Schema", @@ -1586,7 +1586,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Schema", @@ -1675,7 +1675,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Schema", @@ -1763,7 +1763,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Schema", @@ -1848,7 +1848,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Schema", @@ -1932,7 +1932,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Schema", @@ -2013,7 +2013,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_schema" @@ -2090,7 +2090,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_schema" @@ -2168,7 +2168,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Schema", @@ -2248,7 +2248,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Schema", @@ -2329,7 +2329,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.services.schema_service.pagers.ListSchemaRevisionsAsyncPager", @@ -2409,7 +2409,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.services.schema_service.pagers.ListSchemaRevisionsPager", @@ -2490,7 +2490,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.services.schema_service.pagers.ListSchemasAsyncPager", @@ -2570,7 +2570,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.services.schema_service.pagers.ListSchemasPager", @@ -2655,7 +2655,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Schema", @@ -2739,7 +2739,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Schema", @@ -2816,7 +2816,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.ValidateMessageResponse", @@ -2892,7 +2892,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.ValidateMessageResponse", @@ -2977,7 +2977,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.ValidateSchemaResponse", @@ -3061,7 +3061,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.ValidateSchemaResponse", @@ -3146,7 +3146,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "acknowledge" @@ -3227,7 +3227,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "acknowledge" @@ -3309,7 +3309,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Snapshot", @@ -3393,7 +3393,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Snapshot", @@ -3486,7 +3486,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Subscription", @@ -3578,7 +3578,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Subscription", @@ -3659,7 +3659,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_snapshot" @@ -3736,7 +3736,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_snapshot" @@ -3814,7 +3814,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_subscription" @@ -3891,7 +3891,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_subscription" @@ -3969,7 +3969,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Snapshot", @@ -4049,7 +4049,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Snapshot", @@ -4130,7 +4130,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Subscription", @@ -4210,7 +4210,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Subscription", @@ -4291,7 +4291,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.services.subscriber.pagers.ListSnapshotsAsyncPager", @@ -4371,7 +4371,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.services.subscriber.pagers.ListSnapshotsPager", @@ -4452,7 +4452,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.services.subscriber.pagers.ListSubscriptionsAsyncPager", @@ -4532,7 +4532,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.services.subscriber.pagers.ListSubscriptionsPager", @@ -4621,7 +4621,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "modify_ack_deadline" @@ -4706,7 +4706,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "modify_ack_deadline" @@ -4788,7 +4788,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "modify_push_config" @@ -4869,7 +4869,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "modify_push_config" @@ -4955,7 +4955,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.PullResponse", @@ -5043,7 +5043,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.PullResponse", @@ -5120,7 +5120,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.SeekResponse", @@ -5196,7 +5196,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.SeekResponse", @@ -5273,7 +5273,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "Iterable[google.pubsub_v1.types.StreamingPullResponse]", @@ -5349,7 +5349,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "Iterable[google.pubsub_v1.types.StreamingPullResponse]", @@ -5434,7 +5434,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Snapshot", @@ -5518,7 +5518,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Snapshot", @@ -5603,7 +5603,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Subscription", @@ -5687,7 +5687,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.pubsub_v1.types.Subscription", diff --git a/tests/unit/gapic/pubsub_v1/test_publisher.py b/tests/unit/gapic/pubsub_v1/test_publisher.py index 423df4433..4856b1cad 100644 --- a/tests/unit/gapic/pubsub_v1/test_publisher.py +++ b/tests/unit/gapic/pubsub_v1/test_publisher.py @@ -69,6 +69,14 @@ import google.auth +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER chunk = data[i : i + chunk_size] @@ -301,6 +309,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = PublisherClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = PublisherClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4639,6 +4690,7 @@ def test_create_topic_rest_required_fields(request_type=pubsub.Topic): response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.create_topic(request) @@ -4684,6 +4736,7 @@ def test_create_topic_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.create_topic(**mock_args) @@ -4807,6 +4860,7 @@ def test_update_topic_rest_required_fields(request_type=pubsub.UpdateTopicReques response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.update_topic(request) @@ -4861,6 +4915,7 @@ def test_update_topic_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.update_topic(**mock_args) @@ -4990,6 +5045,7 @@ def test_publish_rest_required_fields(request_type=pubsub.PublishRequest): response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.publish(request) @@ -5044,6 +5100,7 @@ def test_publish_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.publish(**mock_args) @@ -5173,6 +5230,7 @@ def test_get_topic_rest_required_fields(request_type=pubsub.GetTopicRequest): response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.get_topic(request) @@ -5218,6 +5276,7 @@ def test_get_topic_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.get_topic(**mock_args) @@ -5352,6 +5411,7 @@ def test_list_topics_rest_required_fields(request_type=pubsub.ListTopicsRequest) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.list_topics(request) @@ -5405,6 +5465,7 @@ def test_list_topics_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.list_topics(**mock_args) @@ -5607,6 +5668,7 @@ def test_list_topic_subscriptions_rest_required_fields( response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.list_topic_subscriptions(request) @@ -5660,6 +5722,7 @@ def test_list_topic_subscriptions_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.list_topic_subscriptions(**mock_args) @@ -5864,6 +5927,7 @@ def test_list_topic_snapshots_rest_required_fields( response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.list_topic_snapshots(request) @@ -5917,6 +5981,7 @@ def test_list_topic_snapshots_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.list_topic_snapshots(**mock_args) @@ -6103,6 +6168,7 @@ def test_delete_topic_rest_required_fields(request_type=pubsub.DeleteTopicReques response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.delete_topic(request) @@ -6146,6 +6212,7 @@ def test_delete_topic_rest_flattened(): json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.delete_topic(**mock_args) @@ -6279,6 +6346,7 @@ def test_detach_subscription_rest_required_fields( response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.detach_subscription(request) @@ -6891,6 +6959,7 @@ def test_create_topic_rest_bad_request(request_type=pubsub.Topic): response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.create_topic(request) @@ -6929,6 +6998,7 @@ def test_create_topic_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.create_topic(request) # Establish that the response is the type that we expect. @@ -6954,10 +7024,13 @@ def test_create_topic_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PublisherRestInterceptor, "post_create_topic" ) as post, mock.patch.object( + transports.PublisherRestInterceptor, "post_create_topic_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.PublisherRestInterceptor, "pre_create_topic" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = pubsub.Topic.pb(pubsub.Topic()) transcode.return_value = { "method": "post", @@ -6968,6 +7041,7 @@ def test_create_topic_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = pubsub.Topic.to_json(pubsub.Topic()) req.return_value.content = return_value @@ -6978,6 +7052,7 @@ def test_create_topic_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = pubsub.Topic() + post_with_metadata.return_value = pubsub.Topic(), metadata client.create_topic( request, @@ -6989,6 +7064,7 @@ def test_create_topic_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_topic_rest_bad_request(request_type=pubsub.UpdateTopicRequest): @@ -7010,6 +7086,7 @@ def test_update_topic_rest_bad_request(request_type=pubsub.UpdateTopicRequest): response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.update_topic(request) @@ -7048,6 +7125,7 @@ def test_update_topic_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.update_topic(request) # Establish that the response is the type that we expect. @@ -7073,10 +7151,13 @@ def test_update_topic_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PublisherRestInterceptor, "post_update_topic" ) as post, mock.patch.object( + transports.PublisherRestInterceptor, "post_update_topic_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.PublisherRestInterceptor, "pre_update_topic" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = pubsub.UpdateTopicRequest.pb(pubsub.UpdateTopicRequest()) transcode.return_value = { "method": "post", @@ -7087,6 +7168,7 @@ def test_update_topic_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = pubsub.Topic.to_json(pubsub.Topic()) req.return_value.content = return_value @@ -7097,6 +7179,7 @@ def test_update_topic_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = pubsub.Topic() + post_with_metadata.return_value = pubsub.Topic(), metadata client.update_topic( request, @@ -7108,6 +7191,7 @@ def test_update_topic_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_publish_rest_bad_request(request_type=pubsub.PublishRequest): @@ -7129,6 +7213,7 @@ def test_publish_rest_bad_request(request_type=pubsub.PublishRequest): response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.publish(request) @@ -7164,6 +7249,7 @@ def test_publish_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.publish(request) # Establish that the response is the type that we expect. @@ -7186,10 +7272,13 @@ def test_publish_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PublisherRestInterceptor, "post_publish" ) as post, mock.patch.object( + transports.PublisherRestInterceptor, "post_publish_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.PublisherRestInterceptor, "pre_publish" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = pubsub.PublishRequest.pb(pubsub.PublishRequest()) transcode.return_value = { "method": "post", @@ -7200,6 +7289,7 @@ def test_publish_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = pubsub.PublishResponse.to_json(pubsub.PublishResponse()) req.return_value.content = return_value @@ -7210,6 +7300,7 @@ def test_publish_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = pubsub.PublishResponse() + post_with_metadata.return_value = pubsub.PublishResponse(), metadata client.publish( request, @@ -7221,6 +7312,7 @@ def test_publish_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_topic_rest_bad_request(request_type=pubsub.GetTopicRequest): @@ -7242,6 +7334,7 @@ def test_get_topic_rest_bad_request(request_type=pubsub.GetTopicRequest): response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.get_topic(request) @@ -7280,6 +7373,7 @@ def test_get_topic_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.get_topic(request) # Establish that the response is the type that we expect. @@ -7305,10 +7399,13 @@ def test_get_topic_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PublisherRestInterceptor, "post_get_topic" ) as post, mock.patch.object( + transports.PublisherRestInterceptor, "post_get_topic_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.PublisherRestInterceptor, "pre_get_topic" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = pubsub.GetTopicRequest.pb(pubsub.GetTopicRequest()) transcode.return_value = { "method": "post", @@ -7319,6 +7416,7 @@ def test_get_topic_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = pubsub.Topic.to_json(pubsub.Topic()) req.return_value.content = return_value @@ -7329,6 +7427,7 @@ def test_get_topic_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = pubsub.Topic() + post_with_metadata.return_value = pubsub.Topic(), metadata client.get_topic( request, @@ -7340,6 +7439,7 @@ def test_get_topic_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_topics_rest_bad_request(request_type=pubsub.ListTopicsRequest): @@ -7361,6 +7461,7 @@ def test_list_topics_rest_bad_request(request_type=pubsub.ListTopicsRequest): response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.list_topics(request) @@ -7396,6 +7497,7 @@ def test_list_topics_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.list_topics(request) # Establish that the response is the type that we expect. @@ -7418,10 +7520,13 @@ def test_list_topics_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PublisherRestInterceptor, "post_list_topics" ) as post, mock.patch.object( + transports.PublisherRestInterceptor, "post_list_topics_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.PublisherRestInterceptor, "pre_list_topics" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = pubsub.ListTopicsRequest.pb(pubsub.ListTopicsRequest()) transcode.return_value = { "method": "post", @@ -7432,6 +7537,7 @@ def test_list_topics_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = pubsub.ListTopicsResponse.to_json(pubsub.ListTopicsResponse()) req.return_value.content = return_value @@ -7442,6 +7548,7 @@ def test_list_topics_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = pubsub.ListTopicsResponse() + post_with_metadata.return_value = pubsub.ListTopicsResponse(), metadata client.list_topics( request, @@ -7453,6 +7560,7 @@ def test_list_topics_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_topic_subscriptions_rest_bad_request( @@ -7476,6 +7584,7 @@ def test_list_topic_subscriptions_rest_bad_request( response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.list_topic_subscriptions(request) @@ -7512,6 +7621,7 @@ def test_list_topic_subscriptions_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.list_topic_subscriptions(request) # Establish that the response is the type that we expect. @@ -7535,10 +7645,14 @@ def test_list_topic_subscriptions_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PublisherRestInterceptor, "post_list_topic_subscriptions" ) as post, mock.patch.object( + transports.PublisherRestInterceptor, + "post_list_topic_subscriptions_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.PublisherRestInterceptor, "pre_list_topic_subscriptions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = pubsub.ListTopicSubscriptionsRequest.pb( pubsub.ListTopicSubscriptionsRequest() ) @@ -7551,6 +7665,7 @@ def test_list_topic_subscriptions_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = pubsub.ListTopicSubscriptionsResponse.to_json( pubsub.ListTopicSubscriptionsResponse() ) @@ -7563,6 +7678,10 @@ def test_list_topic_subscriptions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = pubsub.ListTopicSubscriptionsResponse() + post_with_metadata.return_value = ( + pubsub.ListTopicSubscriptionsResponse(), + metadata, + ) client.list_topic_subscriptions( request, @@ -7574,6 +7693,7 @@ def test_list_topic_subscriptions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_topic_snapshots_rest_bad_request( @@ -7597,6 +7717,7 @@ def test_list_topic_snapshots_rest_bad_request( response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.list_topic_snapshots(request) @@ -7633,6 +7754,7 @@ def test_list_topic_snapshots_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.list_topic_snapshots(request) # Establish that the response is the type that we expect. @@ -7656,10 +7778,13 @@ def test_list_topic_snapshots_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PublisherRestInterceptor, "post_list_topic_snapshots" ) as post, mock.patch.object( + transports.PublisherRestInterceptor, "post_list_topic_snapshots_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.PublisherRestInterceptor, "pre_list_topic_snapshots" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = pubsub.ListTopicSnapshotsRequest.pb( pubsub.ListTopicSnapshotsRequest() ) @@ -7672,6 +7797,7 @@ def test_list_topic_snapshots_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = pubsub.ListTopicSnapshotsResponse.to_json( pubsub.ListTopicSnapshotsResponse() ) @@ -7684,6 +7810,7 @@ def test_list_topic_snapshots_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = pubsub.ListTopicSnapshotsResponse() + post_with_metadata.return_value = pubsub.ListTopicSnapshotsResponse(), metadata client.list_topic_snapshots( request, @@ -7695,6 +7822,7 @@ def test_list_topic_snapshots_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_topic_rest_bad_request(request_type=pubsub.DeleteTopicRequest): @@ -7716,6 +7844,7 @@ def test_delete_topic_rest_bad_request(request_type=pubsub.DeleteTopicRequest): response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.delete_topic(request) @@ -7746,6 +7875,7 @@ def test_delete_topic_rest_call_success(request_type): json_return_value = "" response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.delete_topic(request) # Establish that the response is the type that we expect. @@ -7778,6 +7908,7 @@ def test_delete_topic_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} request = pubsub.DeleteTopicRequest() metadata = [ @@ -7818,6 +7949,7 @@ def test_detach_subscription_rest_bad_request( response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.detach_subscription(request) @@ -7851,6 +7983,7 @@ def test_detach_subscription_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.detach_subscription(request) # Establish that the response is the type that we expect. @@ -7872,10 +8005,13 @@ def test_detach_subscription_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PublisherRestInterceptor, "post_detach_subscription" ) as post, mock.patch.object( + transports.PublisherRestInterceptor, "post_detach_subscription_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.PublisherRestInterceptor, "pre_detach_subscription" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = pubsub.DetachSubscriptionRequest.pb( pubsub.DetachSubscriptionRequest() ) @@ -7888,6 +8024,7 @@ def test_detach_subscription_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = pubsub.DetachSubscriptionResponse.to_json( pubsub.DetachSubscriptionResponse() ) @@ -7900,6 +8037,7 @@ def test_detach_subscription_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = pubsub.DetachSubscriptionResponse() + post_with_metadata.return_value = pubsub.DetachSubscriptionResponse(), metadata client.detach_subscription( request, @@ -7911,6 +8049,7 @@ def test_detach_subscription_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_iam_policy_rest_bad_request( @@ -7936,6 +8075,7 @@ def test_get_iam_policy_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.get_iam_policy(request) @@ -7966,6 +8106,7 @@ def test_get_iam_policy_rest(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.get_iam_policy(request) @@ -7996,6 +8137,7 @@ def test_set_iam_policy_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.set_iam_policy(request) @@ -8026,6 +8168,7 @@ def test_set_iam_policy_rest(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.set_iam_policy(request) @@ -8056,6 +8199,7 @@ def test_test_iam_permissions_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.test_iam_permissions(request) @@ -8086,6 +8230,7 @@ def test_test_iam_permissions_rest(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.test_iam_permissions(request) diff --git a/tests/unit/gapic/pubsub_v1/test_schema_service.py b/tests/unit/gapic/pubsub_v1/test_schema_service.py index 3dbefc470..194cddacf 100644 --- a/tests/unit/gapic/pubsub_v1/test_schema_service.py +++ b/tests/unit/gapic/pubsub_v1/test_schema_service.py @@ -67,6 +67,14 @@ import google.auth +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER chunk = data[i : i + chunk_size] @@ -320,6 +328,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SchemaServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SchemaServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4840,6 +4891,7 @@ def test_create_schema_rest_required_fields(request_type=gp_schema.CreateSchemaR response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.create_schema(request) @@ -4895,6 +4947,7 @@ def test_create_schema_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.create_schema(**mock_args) @@ -5026,6 +5079,7 @@ def test_get_schema_rest_required_fields(request_type=schema.GetSchemaRequest): response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.get_schema(request) @@ -5071,6 +5125,7 @@ def test_get_schema_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.get_schema(**mock_args) @@ -5206,6 +5261,7 @@ def test_list_schemas_rest_required_fields(request_type=schema.ListSchemasReques response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.list_schemas(request) @@ -5260,6 +5316,7 @@ def test_list_schemas_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.list_schemas(**mock_args) @@ -5463,6 +5520,7 @@ def test_list_schema_revisions_rest_required_fields( response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.list_schema_revisions(request) @@ -5517,6 +5575,7 @@ def test_list_schema_revisions_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.list_schema_revisions(**mock_args) @@ -5709,6 +5768,7 @@ def test_commit_schema_rest_required_fields(request_type=gp_schema.CommitSchemaR response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.commit_schema(request) @@ -5763,6 +5823,7 @@ def test_commit_schema_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.commit_schema(**mock_args) @@ -5898,6 +5959,7 @@ def test_rollback_schema_rest_required_fields( response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.rollback_schema(request) @@ -5952,6 +6014,7 @@ def test_rollback_schema_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.rollback_schema(**mock_args) @@ -6090,6 +6153,7 @@ def test_delete_schema_revision_rest_required_fields( response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.delete_schema_revision(request) @@ -6136,6 +6200,7 @@ def test_delete_schema_revision_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.delete_schema_revision(**mock_args) @@ -6262,6 +6327,7 @@ def test_delete_schema_rest_required_fields(request_type=schema.DeleteSchemaRequ response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.delete_schema(request) @@ -6305,6 +6371,7 @@ def test_delete_schema_rest_flattened(): json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.delete_schema(**mock_args) @@ -6435,6 +6502,7 @@ def test_validate_schema_rest_required_fields( response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.validate_schema(request) @@ -6489,6 +6557,7 @@ def test_validate_schema_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.validate_schema(**mock_args) @@ -6623,6 +6692,7 @@ def test_validate_message_rest_required_fields( response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.validate_message(request) @@ -7281,6 +7351,7 @@ def test_create_schema_rest_bad_request(request_type=gp_schema.CreateSchemaReque response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.create_schema(request) @@ -7393,6 +7464,7 @@ def get_message_fields(field): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.create_schema(request) # Establish that the response is the type that we expect. @@ -7420,10 +7492,13 @@ def test_create_schema_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SchemaServiceRestInterceptor, "post_create_schema" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, "post_create_schema_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_create_schema" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gp_schema.CreateSchemaRequest.pb(gp_schema.CreateSchemaRequest()) transcode.return_value = { "method": "post", @@ -7434,6 +7509,7 @@ def test_create_schema_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = gp_schema.Schema.to_json(gp_schema.Schema()) req.return_value.content = return_value @@ -7444,6 +7520,7 @@ def test_create_schema_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gp_schema.Schema() + post_with_metadata.return_value = gp_schema.Schema(), metadata client.create_schema( request, @@ -7455,6 +7532,7 @@ def test_create_schema_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_schema_rest_bad_request(request_type=schema.GetSchemaRequest): @@ -7476,6 +7554,7 @@ def test_get_schema_rest_bad_request(request_type=schema.GetSchemaRequest): response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.get_schema(request) @@ -7514,6 +7593,7 @@ def test_get_schema_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.get_schema(request) # Establish that the response is the type that we expect. @@ -7541,10 +7621,13 @@ def test_get_schema_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SchemaServiceRestInterceptor, "post_get_schema" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, "post_get_schema_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_get_schema" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = schema.GetSchemaRequest.pb(schema.GetSchemaRequest()) transcode.return_value = { "method": "post", @@ -7555,6 +7638,7 @@ def test_get_schema_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = schema.Schema.to_json(schema.Schema()) req.return_value.content = return_value @@ -7565,6 +7649,7 @@ def test_get_schema_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = schema.Schema() + post_with_metadata.return_value = schema.Schema(), metadata client.get_schema( request, @@ -7576,6 +7661,7 @@ def test_get_schema_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_schemas_rest_bad_request(request_type=schema.ListSchemasRequest): @@ -7597,6 +7683,7 @@ def test_list_schemas_rest_bad_request(request_type=schema.ListSchemasRequest): response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.list_schemas(request) @@ -7632,6 +7719,7 @@ def test_list_schemas_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.list_schemas(request) # Establish that the response is the type that we expect. @@ -7656,10 +7744,13 @@ def test_list_schemas_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SchemaServiceRestInterceptor, "post_list_schemas" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, "post_list_schemas_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_list_schemas" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = schema.ListSchemasRequest.pb(schema.ListSchemasRequest()) transcode.return_value = { "method": "post", @@ -7670,6 +7761,7 @@ def test_list_schemas_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = schema.ListSchemasResponse.to_json(schema.ListSchemasResponse()) req.return_value.content = return_value @@ -7680,6 +7772,7 @@ def test_list_schemas_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = schema.ListSchemasResponse() + post_with_metadata.return_value = schema.ListSchemasResponse(), metadata client.list_schemas( request, @@ -7691,6 +7784,7 @@ def test_list_schemas_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_schema_revisions_rest_bad_request( @@ -7714,6 +7808,7 @@ def test_list_schema_revisions_rest_bad_request( response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.list_schema_revisions(request) @@ -7749,6 +7844,7 @@ def test_list_schema_revisions_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.list_schema_revisions(request) # Establish that the response is the type that we expect. @@ -7773,10 +7869,14 @@ def test_list_schema_revisions_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SchemaServiceRestInterceptor, "post_list_schema_revisions" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, + "post_list_schema_revisions_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_list_schema_revisions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = schema.ListSchemaRevisionsRequest.pb( schema.ListSchemaRevisionsRequest() ) @@ -7789,6 +7889,7 @@ def test_list_schema_revisions_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = schema.ListSchemaRevisionsResponse.to_json( schema.ListSchemaRevisionsResponse() ) @@ -7801,6 +7902,7 @@ def test_list_schema_revisions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = schema.ListSchemaRevisionsResponse() + post_with_metadata.return_value = schema.ListSchemaRevisionsResponse(), metadata client.list_schema_revisions( request, @@ -7812,6 +7914,7 @@ def test_list_schema_revisions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_commit_schema_rest_bad_request(request_type=gp_schema.CommitSchemaRequest): @@ -7833,6 +7936,7 @@ def test_commit_schema_rest_bad_request(request_type=gp_schema.CommitSchemaReque response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.commit_schema(request) @@ -7871,6 +7975,7 @@ def test_commit_schema_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.commit_schema(request) # Establish that the response is the type that we expect. @@ -7898,10 +8003,13 @@ def test_commit_schema_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SchemaServiceRestInterceptor, "post_commit_schema" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, "post_commit_schema_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_commit_schema" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gp_schema.CommitSchemaRequest.pb(gp_schema.CommitSchemaRequest()) transcode.return_value = { "method": "post", @@ -7912,6 +8020,7 @@ def test_commit_schema_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = gp_schema.Schema.to_json(gp_schema.Schema()) req.return_value.content = return_value @@ -7922,6 +8031,7 @@ def test_commit_schema_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gp_schema.Schema() + post_with_metadata.return_value = gp_schema.Schema(), metadata client.commit_schema( request, @@ -7933,6 +8043,7 @@ def test_commit_schema_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_rollback_schema_rest_bad_request(request_type=schema.RollbackSchemaRequest): @@ -7954,6 +8065,7 @@ def test_rollback_schema_rest_bad_request(request_type=schema.RollbackSchemaRequ response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.rollback_schema(request) @@ -7992,6 +8104,7 @@ def test_rollback_schema_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.rollback_schema(request) # Establish that the response is the type that we expect. @@ -8019,10 +8132,13 @@ def test_rollback_schema_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SchemaServiceRestInterceptor, "post_rollback_schema" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, "post_rollback_schema_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_rollback_schema" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = schema.RollbackSchemaRequest.pb(schema.RollbackSchemaRequest()) transcode.return_value = { "method": "post", @@ -8033,6 +8149,7 @@ def test_rollback_schema_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = schema.Schema.to_json(schema.Schema()) req.return_value.content = return_value @@ -8043,6 +8160,7 @@ def test_rollback_schema_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = schema.Schema() + post_with_metadata.return_value = schema.Schema(), metadata client.rollback_schema( request, @@ -8054,6 +8172,7 @@ def test_rollback_schema_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_schema_revision_rest_bad_request( @@ -8077,6 +8196,7 @@ def test_delete_schema_revision_rest_bad_request( response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.delete_schema_revision(request) @@ -8115,6 +8235,7 @@ def test_delete_schema_revision_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.delete_schema_revision(request) # Establish that the response is the type that we expect. @@ -8142,10 +8263,14 @@ def test_delete_schema_revision_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SchemaServiceRestInterceptor, "post_delete_schema_revision" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, + "post_delete_schema_revision_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_delete_schema_revision" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = schema.DeleteSchemaRevisionRequest.pb( schema.DeleteSchemaRevisionRequest() ) @@ -8158,6 +8283,7 @@ def test_delete_schema_revision_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = schema.Schema.to_json(schema.Schema()) req.return_value.content = return_value @@ -8168,6 +8294,7 @@ def test_delete_schema_revision_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = schema.Schema() + post_with_metadata.return_value = schema.Schema(), metadata client.delete_schema_revision( request, @@ -8179,6 +8306,7 @@ def test_delete_schema_revision_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_schema_rest_bad_request(request_type=schema.DeleteSchemaRequest): @@ -8200,6 +8328,7 @@ def test_delete_schema_rest_bad_request(request_type=schema.DeleteSchemaRequest) response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.delete_schema(request) @@ -8230,6 +8359,7 @@ def test_delete_schema_rest_call_success(request_type): json_return_value = "" response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.delete_schema(request) # Establish that the response is the type that we expect. @@ -8264,6 +8394,7 @@ def test_delete_schema_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} request = schema.DeleteSchemaRequest() metadata = [ @@ -8302,6 +8433,7 @@ def test_validate_schema_rest_bad_request(request_type=gp_schema.ValidateSchemaR response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.validate_schema(request) @@ -8335,6 +8467,7 @@ def test_validate_schema_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.validate_schema(request) # Establish that the response is the type that we expect. @@ -8358,10 +8491,13 @@ def test_validate_schema_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SchemaServiceRestInterceptor, "post_validate_schema" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, "post_validate_schema_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_validate_schema" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gp_schema.ValidateSchemaRequest.pb( gp_schema.ValidateSchemaRequest() ) @@ -8374,6 +8510,7 @@ def test_validate_schema_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = gp_schema.ValidateSchemaResponse.to_json( gp_schema.ValidateSchemaResponse() ) @@ -8386,6 +8523,7 @@ def test_validate_schema_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gp_schema.ValidateSchemaResponse() + post_with_metadata.return_value = gp_schema.ValidateSchemaResponse(), metadata client.validate_schema( request, @@ -8397,6 +8535,7 @@ def test_validate_schema_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_validate_message_rest_bad_request(request_type=schema.ValidateMessageRequest): @@ -8418,6 +8557,7 @@ def test_validate_message_rest_bad_request(request_type=schema.ValidateMessageRe response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.validate_message(request) @@ -8451,6 +8591,7 @@ def test_validate_message_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.validate_message(request) # Establish that the response is the type that we expect. @@ -8474,10 +8615,13 @@ def test_validate_message_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SchemaServiceRestInterceptor, "post_validate_message" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, "post_validate_message_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_validate_message" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = schema.ValidateMessageRequest.pb(schema.ValidateMessageRequest()) transcode.return_value = { "method": "post", @@ -8488,6 +8632,7 @@ def test_validate_message_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = schema.ValidateMessageResponse.to_json( schema.ValidateMessageResponse() ) @@ -8500,6 +8645,7 @@ def test_validate_message_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = schema.ValidateMessageResponse() + post_with_metadata.return_value = schema.ValidateMessageResponse(), metadata client.validate_message( request, @@ -8511,6 +8657,7 @@ def test_validate_message_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_iam_policy_rest_bad_request( @@ -8536,6 +8683,7 @@ def test_get_iam_policy_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.get_iam_policy(request) @@ -8566,6 +8714,7 @@ def test_get_iam_policy_rest(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.get_iam_policy(request) @@ -8596,6 +8745,7 @@ def test_set_iam_policy_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.set_iam_policy(request) @@ -8626,6 +8776,7 @@ def test_set_iam_policy_rest(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.set_iam_policy(request) @@ -8656,6 +8807,7 @@ def test_test_iam_permissions_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.test_iam_permissions(request) @@ -8686,6 +8838,7 @@ def test_test_iam_permissions_rest(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.test_iam_permissions(request) diff --git a/tests/unit/gapic/pubsub_v1/test_subscriber.py b/tests/unit/gapic/pubsub_v1/test_subscriber.py index 4478942f7..966e30957 100644 --- a/tests/unit/gapic/pubsub_v1/test_subscriber.py +++ b/tests/unit/gapic/pubsub_v1/test_subscriber.py @@ -69,6 +69,14 @@ import google.auth +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER chunk = data[i : i + chunk_size] @@ -303,6 +311,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SubscriberClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SubscriberClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -6683,6 +6734,7 @@ def test_create_subscription_rest_required_fields(request_type=pubsub.Subscripti response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.create_subscription(request) @@ -6739,6 +6791,7 @@ def test_create_subscription_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.create_subscription(**mock_args) @@ -6873,6 +6926,7 @@ def test_get_subscription_rest_required_fields( response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.get_subscription(request) @@ -6918,6 +6972,7 @@ def test_get_subscription_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.get_subscription(**mock_args) @@ -7048,6 +7103,7 @@ def test_update_subscription_rest_required_fields( response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.update_subscription(request) @@ -7104,6 +7160,7 @@ def test_update_subscription_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.update_subscription(**mock_args) @@ -7247,6 +7304,7 @@ def test_list_subscriptions_rest_required_fields( response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.list_subscriptions(request) @@ -7300,6 +7358,7 @@ def test_list_subscriptions_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.list_subscriptions(**mock_args) @@ -7491,6 +7550,7 @@ def test_delete_subscription_rest_required_fields( response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.delete_subscription(request) @@ -7534,6 +7594,7 @@ def test_delete_subscription_rest_flattened(): json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.delete_subscription(**mock_args) @@ -7674,6 +7735,7 @@ def test_modify_ack_deadline_rest_required_fields( response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.modify_ack_deadline(request) @@ -7728,6 +7790,7 @@ def test_modify_ack_deadline_rest_flattened(): json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.modify_ack_deadline(**mock_args) @@ -7861,6 +7924,7 @@ def test_acknowledge_rest_required_fields(request_type=pubsub.AcknowledgeRequest response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.acknowledge(request) @@ -7913,6 +7977,7 @@ def test_acknowledge_rest_flattened(): json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.acknowledge(**mock_args) @@ -8048,6 +8113,7 @@ def test_pull_rest_required_fields(request_type=pubsub.PullRequest): response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.pull(request) @@ -8103,6 +8169,7 @@ def test_pull_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.pull(**mock_args) @@ -8249,6 +8316,7 @@ def test_modify_push_config_rest_required_fields( response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.modify_push_config(request) @@ -8301,6 +8369,7 @@ def test_modify_push_config_rest_flattened(): json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.modify_push_config(**mock_args) @@ -8431,6 +8500,7 @@ def test_get_snapshot_rest_required_fields(request_type=pubsub.GetSnapshotReques response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.get_snapshot(request) @@ -8476,6 +8546,7 @@ def test_get_snapshot_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.get_snapshot(**mock_args) @@ -8610,6 +8681,7 @@ def test_list_snapshots_rest_required_fields(request_type=pubsub.ListSnapshotsRe response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.list_snapshots(request) @@ -8663,6 +8735,7 @@ def test_list_snapshots_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.list_snapshots(**mock_args) @@ -8858,6 +8931,7 @@ def test_create_snapshot_rest_required_fields( response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.create_snapshot(request) @@ -8912,6 +8986,7 @@ def test_create_snapshot_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.create_snapshot(**mock_args) @@ -9038,6 +9113,7 @@ def test_update_snapshot_rest_required_fields( response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.update_snapshot(request) @@ -9092,6 +9168,7 @@ def test_update_snapshot_rest_flattened(): json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.update_snapshot(**mock_args) @@ -9220,6 +9297,7 @@ def test_delete_snapshot_rest_required_fields( response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.delete_snapshot(request) @@ -9263,6 +9341,7 @@ def test_delete_snapshot_rest_flattened(): json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.delete_snapshot(**mock_args) @@ -9391,6 +9470,7 @@ def test_seek_rest_required_fields(request_type=pubsub.SeekRequest): response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.seek(request) @@ -10310,6 +10390,7 @@ def test_create_subscription_rest_bad_request(request_type=pubsub.Subscription): response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.create_subscription(request) @@ -10353,6 +10434,7 @@ def test_create_subscription_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.create_subscription(request) # Establish that the response is the type that we expect. @@ -10385,10 +10467,13 @@ def test_create_subscription_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SubscriberRestInterceptor, "post_create_subscription" ) as post, mock.patch.object( + transports.SubscriberRestInterceptor, "post_create_subscription_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SubscriberRestInterceptor, "pre_create_subscription" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = pubsub.Subscription.pb(pubsub.Subscription()) transcode.return_value = { "method": "post", @@ -10399,6 +10484,7 @@ def test_create_subscription_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = pubsub.Subscription.to_json(pubsub.Subscription()) req.return_value.content = return_value @@ -10409,6 +10495,7 @@ def test_create_subscription_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = pubsub.Subscription() + post_with_metadata.return_value = pubsub.Subscription(), metadata client.create_subscription( request, @@ -10420,6 +10507,7 @@ def test_create_subscription_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_subscription_rest_bad_request(request_type=pubsub.GetSubscriptionRequest): @@ -10441,6 +10529,7 @@ def test_get_subscription_rest_bad_request(request_type=pubsub.GetSubscriptionRe response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.get_subscription(request) @@ -10484,6 +10573,7 @@ def test_get_subscription_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.get_subscription(request) # Establish that the response is the type that we expect. @@ -10516,10 +10606,13 @@ def test_get_subscription_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SubscriberRestInterceptor, "post_get_subscription" ) as post, mock.patch.object( + transports.SubscriberRestInterceptor, "post_get_subscription_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SubscriberRestInterceptor, "pre_get_subscription" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = pubsub.GetSubscriptionRequest.pb(pubsub.GetSubscriptionRequest()) transcode.return_value = { "method": "post", @@ -10530,6 +10623,7 @@ def test_get_subscription_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = pubsub.Subscription.to_json(pubsub.Subscription()) req.return_value.content = return_value @@ -10540,6 +10634,7 @@ def test_get_subscription_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = pubsub.Subscription() + post_with_metadata.return_value = pubsub.Subscription(), metadata client.get_subscription( request, @@ -10551,6 +10646,7 @@ def test_get_subscription_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_subscription_rest_bad_request( @@ -10574,6 +10670,7 @@ def test_update_subscription_rest_bad_request( response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.update_subscription(request) @@ -10617,6 +10714,7 @@ def test_update_subscription_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.update_subscription(request) # Establish that the response is the type that we expect. @@ -10649,10 +10747,13 @@ def test_update_subscription_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SubscriberRestInterceptor, "post_update_subscription" ) as post, mock.patch.object( + transports.SubscriberRestInterceptor, "post_update_subscription_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SubscriberRestInterceptor, "pre_update_subscription" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = pubsub.UpdateSubscriptionRequest.pb( pubsub.UpdateSubscriptionRequest() ) @@ -10665,6 +10766,7 @@ def test_update_subscription_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = pubsub.Subscription.to_json(pubsub.Subscription()) req.return_value.content = return_value @@ -10675,6 +10777,7 @@ def test_update_subscription_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = pubsub.Subscription() + post_with_metadata.return_value = pubsub.Subscription(), metadata client.update_subscription( request, @@ -10686,6 +10789,7 @@ def test_update_subscription_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_subscriptions_rest_bad_request( @@ -10709,6 +10813,7 @@ def test_list_subscriptions_rest_bad_request( response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.list_subscriptions(request) @@ -10744,6 +10849,7 @@ def test_list_subscriptions_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.list_subscriptions(request) # Establish that the response is the type that we expect. @@ -10768,10 +10874,13 @@ def test_list_subscriptions_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SubscriberRestInterceptor, "post_list_subscriptions" ) as post, mock.patch.object( + transports.SubscriberRestInterceptor, "post_list_subscriptions_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SubscriberRestInterceptor, "pre_list_subscriptions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = pubsub.ListSubscriptionsRequest.pb( pubsub.ListSubscriptionsRequest() ) @@ -10784,6 +10893,7 @@ def test_list_subscriptions_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = pubsub.ListSubscriptionsResponse.to_json( pubsub.ListSubscriptionsResponse() ) @@ -10796,6 +10906,7 @@ def test_list_subscriptions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = pubsub.ListSubscriptionsResponse() + post_with_metadata.return_value = pubsub.ListSubscriptionsResponse(), metadata client.list_subscriptions( request, @@ -10807,6 +10918,7 @@ def test_list_subscriptions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_subscription_rest_bad_request( @@ -10830,6 +10942,7 @@ def test_delete_subscription_rest_bad_request( response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.delete_subscription(request) @@ -10860,6 +10973,7 @@ def test_delete_subscription_rest_call_success(request_type): json_return_value = "" response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.delete_subscription(request) # Establish that the response is the type that we expect. @@ -10896,6 +11010,7 @@ def test_delete_subscription_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} request = pubsub.DeleteSubscriptionRequest() metadata = [ @@ -10936,6 +11051,7 @@ def test_modify_ack_deadline_rest_bad_request( response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.modify_ack_deadline(request) @@ -10966,6 +11082,7 @@ def test_modify_ack_deadline_rest_call_success(request_type): json_return_value = "" response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.modify_ack_deadline(request) # Establish that the response is the type that we expect. @@ -11002,6 +11119,7 @@ def test_modify_ack_deadline_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} request = pubsub.ModifyAckDeadlineRequest() metadata = [ @@ -11040,6 +11158,7 @@ def test_acknowledge_rest_bad_request(request_type=pubsub.AcknowledgeRequest): response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.acknowledge(request) @@ -11070,6 +11189,7 @@ def test_acknowledge_rest_call_success(request_type): json_return_value = "" response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.acknowledge(request) # Establish that the response is the type that we expect. @@ -11104,6 +11224,7 @@ def test_acknowledge_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} request = pubsub.AcknowledgeRequest() metadata = [ @@ -11142,6 +11263,7 @@ def test_pull_rest_bad_request(request_type=pubsub.PullRequest): response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.pull(request) @@ -11175,6 +11297,7 @@ def test_pull_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.pull(request) # Establish that the response is the type that we expect. @@ -11198,10 +11321,13 @@ def test_pull_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SubscriberRestInterceptor, "post_pull" ) as post, mock.patch.object( + transports.SubscriberRestInterceptor, "post_pull_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SubscriberRestInterceptor, "pre_pull" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = pubsub.PullRequest.pb(pubsub.PullRequest()) transcode.return_value = { "method": "post", @@ -11212,6 +11338,7 @@ def test_pull_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = pubsub.PullResponse.to_json(pubsub.PullResponse()) req.return_value.content = return_value @@ -11222,6 +11349,7 @@ def test_pull_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = pubsub.PullResponse() + post_with_metadata.return_value = pubsub.PullResponse(), metadata client.pull( request, @@ -11233,6 +11361,7 @@ def test_pull_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_streaming_pull_rest_error(): @@ -11268,6 +11397,7 @@ def test_modify_push_config_rest_bad_request( response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.modify_push_config(request) @@ -11298,6 +11428,7 @@ def test_modify_push_config_rest_call_success(request_type): json_return_value = "" response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.modify_push_config(request) # Establish that the response is the type that we expect. @@ -11332,6 +11463,7 @@ def test_modify_push_config_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} request = pubsub.ModifyPushConfigRequest() metadata = [ @@ -11370,6 +11502,7 @@ def test_get_snapshot_rest_bad_request(request_type=pubsub.GetSnapshotRequest): response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.get_snapshot(request) @@ -11406,6 +11539,7 @@ def test_get_snapshot_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.get_snapshot(request) # Establish that the response is the type that we expect. @@ -11431,10 +11565,13 @@ def test_get_snapshot_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SubscriberRestInterceptor, "post_get_snapshot" ) as post, mock.patch.object( + transports.SubscriberRestInterceptor, "post_get_snapshot_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SubscriberRestInterceptor, "pre_get_snapshot" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = pubsub.GetSnapshotRequest.pb(pubsub.GetSnapshotRequest()) transcode.return_value = { "method": "post", @@ -11445,6 +11582,7 @@ def test_get_snapshot_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = pubsub.Snapshot.to_json(pubsub.Snapshot()) req.return_value.content = return_value @@ -11455,6 +11593,7 @@ def test_get_snapshot_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = pubsub.Snapshot() + post_with_metadata.return_value = pubsub.Snapshot(), metadata client.get_snapshot( request, @@ -11466,6 +11605,7 @@ def test_get_snapshot_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_snapshots_rest_bad_request(request_type=pubsub.ListSnapshotsRequest): @@ -11487,6 +11627,7 @@ def test_list_snapshots_rest_bad_request(request_type=pubsub.ListSnapshotsReques response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.list_snapshots(request) @@ -11522,6 +11663,7 @@ def test_list_snapshots_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.list_snapshots(request) # Establish that the response is the type that we expect. @@ -11546,10 +11688,13 @@ def test_list_snapshots_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SubscriberRestInterceptor, "post_list_snapshots" ) as post, mock.patch.object( + transports.SubscriberRestInterceptor, "post_list_snapshots_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SubscriberRestInterceptor, "pre_list_snapshots" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = pubsub.ListSnapshotsRequest.pb(pubsub.ListSnapshotsRequest()) transcode.return_value = { "method": "post", @@ -11560,6 +11705,7 @@ def test_list_snapshots_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = pubsub.ListSnapshotsResponse.to_json( pubsub.ListSnapshotsResponse() ) @@ -11572,6 +11718,7 @@ def test_list_snapshots_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = pubsub.ListSnapshotsResponse() + post_with_metadata.return_value = pubsub.ListSnapshotsResponse(), metadata client.list_snapshots( request, @@ -11583,6 +11730,7 @@ def test_list_snapshots_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_snapshot_rest_bad_request(request_type=pubsub.CreateSnapshotRequest): @@ -11604,6 +11752,7 @@ def test_create_snapshot_rest_bad_request(request_type=pubsub.CreateSnapshotRequ response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.create_snapshot(request) @@ -11640,6 +11789,7 @@ def test_create_snapshot_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.create_snapshot(request) # Establish that the response is the type that we expect. @@ -11665,10 +11815,13 @@ def test_create_snapshot_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SubscriberRestInterceptor, "post_create_snapshot" ) as post, mock.patch.object( + transports.SubscriberRestInterceptor, "post_create_snapshot_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SubscriberRestInterceptor, "pre_create_snapshot" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = pubsub.CreateSnapshotRequest.pb(pubsub.CreateSnapshotRequest()) transcode.return_value = { "method": "post", @@ -11679,6 +11832,7 @@ def test_create_snapshot_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = pubsub.Snapshot.to_json(pubsub.Snapshot()) req.return_value.content = return_value @@ -11689,6 +11843,7 @@ def test_create_snapshot_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = pubsub.Snapshot() + post_with_metadata.return_value = pubsub.Snapshot(), metadata client.create_snapshot( request, @@ -11700,6 +11855,7 @@ def test_create_snapshot_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_snapshot_rest_bad_request(request_type=pubsub.UpdateSnapshotRequest): @@ -11721,6 +11877,7 @@ def test_update_snapshot_rest_bad_request(request_type=pubsub.UpdateSnapshotRequ response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.update_snapshot(request) @@ -11757,6 +11914,7 @@ def test_update_snapshot_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.update_snapshot(request) # Establish that the response is the type that we expect. @@ -11782,10 +11940,13 @@ def test_update_snapshot_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SubscriberRestInterceptor, "post_update_snapshot" ) as post, mock.patch.object( + transports.SubscriberRestInterceptor, "post_update_snapshot_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SubscriberRestInterceptor, "pre_update_snapshot" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = pubsub.UpdateSnapshotRequest.pb(pubsub.UpdateSnapshotRequest()) transcode.return_value = { "method": "post", @@ -11796,6 +11957,7 @@ def test_update_snapshot_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = pubsub.Snapshot.to_json(pubsub.Snapshot()) req.return_value.content = return_value @@ -11806,6 +11968,7 @@ def test_update_snapshot_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = pubsub.Snapshot() + post_with_metadata.return_value = pubsub.Snapshot(), metadata client.update_snapshot( request, @@ -11817,6 +11980,7 @@ def test_update_snapshot_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_snapshot_rest_bad_request(request_type=pubsub.DeleteSnapshotRequest): @@ -11838,6 +12002,7 @@ def test_delete_snapshot_rest_bad_request(request_type=pubsub.DeleteSnapshotRequ response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.delete_snapshot(request) @@ -11868,6 +12033,7 @@ def test_delete_snapshot_rest_call_success(request_type): json_return_value = "" response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.delete_snapshot(request) # Establish that the response is the type that we expect. @@ -11902,6 +12068,7 @@ def test_delete_snapshot_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} request = pubsub.DeleteSnapshotRequest() metadata = [ @@ -11940,6 +12107,7 @@ def test_seek_rest_bad_request(request_type=pubsub.SeekRequest): response_value.status_code = 400 response_value.request = mock.Mock() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.seek(request) @@ -11973,6 +12141,7 @@ def test_seek_rest_call_success(request_type): json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.seek(request) # Establish that the response is the type that we expect. @@ -11996,10 +12165,13 @@ def test_seek_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SubscriberRestInterceptor, "post_seek" ) as post, mock.patch.object( + transports.SubscriberRestInterceptor, "post_seek_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SubscriberRestInterceptor, "pre_seek" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = pubsub.SeekRequest.pb(pubsub.SeekRequest()) transcode.return_value = { "method": "post", @@ -12010,6 +12182,7 @@ def test_seek_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} return_value = pubsub.SeekResponse.to_json(pubsub.SeekResponse()) req.return_value.content = return_value @@ -12020,6 +12193,7 @@ def test_seek_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = pubsub.SeekResponse() + post_with_metadata.return_value = pubsub.SeekResponse(), metadata client.seek( request, @@ -12031,6 +12205,7 @@ def test_seek_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_iam_policy_rest_bad_request( @@ -12056,6 +12231,7 @@ def test_get_iam_policy_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.get_iam_policy(request) @@ -12086,6 +12262,7 @@ def test_get_iam_policy_rest(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.get_iam_policy(request) @@ -12116,6 +12293,7 @@ def test_set_iam_policy_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.set_iam_policy(request) @@ -12146,6 +12324,7 @@ def test_set_iam_policy_rest(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.set_iam_policy(request) @@ -12176,6 +12355,7 @@ def test_test_iam_permissions_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} client.test_iam_permissions(request) @@ -12206,6 +12386,7 @@ def test_test_iam_permissions_rest(request_type): response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.test_iam_permissions(request)