From 8b9c7bf3bb1c4f0beabd71a45c469fcedb19a2c8 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Thu, 12 Dec 2024 15:33:13 -0500 Subject: [PATCH] feat: [Many APIs] Add support for opt-in debug logging (#13349) - [ ] Regenerate this pull request now. fix: Fix typing issue with gRPC metadata when key ends in -bin chore: Update gapic-generator-python to v1.21.0 PiperOrigin-RevId: 705285820 Source-Link: https://github.com/googleapis/googleapis/commit/f9b8b9150f7fcd600b0acaeef91236b1843f5e49 Source-Link: https://github.com/googleapis/googleapis-gen/commit/ca1e0a1e472d6e6f5de883a5cb54724f112ce348 Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLW1hcHMtbWFwc3BsYXRmb3JtZGF0YXNldHMvLk93bEJvdC55YW1sIiwiaCI6ImNhMWUwYTFlNDcyZDZlNmY1ZGU4ODNhNWNiNTQ3MjRmMTEyY2UzNDgifQ== Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLW1hcHMtcGxhY2VzLy5Pd2xCb3QueWFtbCIsImgiOiJjYTFlMGExZTQ3MmQ2ZTZmNWRlODgzYTVjYjU0NzI0ZjExMmNlMzQ4In0= Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLW1hcHMtcm91dGVvcHRpbWl6YXRpb24vLk93bEJvdC55YW1sIiwiaCI6ImNhMWUwYTFlNDcyZDZlNmY1ZGU4ODNhNWNiNTQ3MjRmMTEyY2UzNDgifQ== Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLW1hcHMtcm91dGluZy8uT3dsQm90LnlhbWwiLCJoIjoiY2ExZTBhMWU0NzJkNmU2ZjVkZTg4M2E1Y2I1NDcyNGYxMTJjZTM0OCJ9 Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLW1hcHMtc29sYXIvLk93bEJvdC55YW1sIiwiaCI6ImNhMWUwYTFlNDcyZDZlNmY1ZGU4ODNhNWNiNTQ3MjRmMTEyY2UzNDgifQ== Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLXNob3BwaW5nLW1lcmNoYW50LWFjY291bnRzLy5Pd2xCb3QueWFtbCIsImgiOiJjYTFlMGExZTQ3MmQ2ZTZmNWRlODgzYTVjYjU0NzI0ZjExMmNlMzQ4In0= Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLXNob3BwaW5nLW1lcmNoYW50LWNvbnZlcnNpb25zLy5Pd2xCb3QueWFtbCIsImgiOiJjYTFlMGExZTQ3MmQ2ZTZmNWRlODgzYTVjYjU0NzI0ZjExMmNlMzQ4In0= Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLXNob3BwaW5nLW1lcmNoYW50LWRhdGFzb3VyY2VzLy5Pd2xCb3QueWFtbCIsImgiOiJjYTFlMGExZTQ3MmQ2ZTZmNWRlODgzYTVjYjU0NzI0ZjExMmNlMzQ4In0= Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLXNob3BwaW5nLW1lcmNoYW50LWludmVudG9yaWVzLy5Pd2xCb3QueWFtbCIsImgiOiJjYTFlMGExZTQ3MmQ2ZTZmNWRlODgzYTVjYjU0NzI0ZjExMmNlMzQ4In0= Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLXNob3BwaW5nLW1lcmNoYW50LWxmcC8uT3dsQm90LnlhbWwiLCJoIjoiY2ExZTBhMWU0NzJkNmU2ZjVkZTg4M2E1Y2I1NDcyNGYxMTJjZTM0OCJ9 Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLXNob3BwaW5nLW1lcmNoYW50LW5vdGlmaWNhdGlvbnMvLk93bEJvdC55YW1sIiwiaCI6ImNhMWUwYTFlNDcyZDZlNmY1ZGU4ODNhNWNiNTQ3MjRmMTEyY2UzNDgifQ== Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLXNob3BwaW5nLW1lcmNoYW50LXByb21vdGlvbnMvLk93bEJvdC55YW1sIiwiaCI6ImNhMWUwYTFlNDcyZDZlNmY1ZGU4ODNhNWNiNTQ3MjRmMTEyY2UzNDgifQ== Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLXNob3BwaW5nLW1lcmNoYW50LXF1b3RhLy5Pd2xCb3QueWFtbCIsImgiOiJjYTFlMGExZTQ3MmQ2ZTZmNWRlODgzYTVjYjU0NzI0ZjExMmNlMzQ4In0= Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLXNob3BwaW5nLW1lcmNoYW50LXJlcG9ydHMvLk93bEJvdC55YW1sIiwiaCI6ImNhMWUwYTFlNDcyZDZlNmY1ZGU4ODNhNWNiNTQ3MjRmMTEyY2UzNDgifQ== Copy-Tag: eyJwIjoicGFja2FnZXMvZ3JhZmVhcy8uT3dsQm90LnlhbWwiLCJoIjoiY2ExZTBhMWU0NzJkNmU2ZjVkZTg4M2E1Y2I1NDcyNGYxMTJjZTM0OCJ9 --------- Co-authored-by: Owl Bot Co-authored-by: ohmayr Co-authored-by: Anthonios Partheniou --- .../mapsplatformdatasets/gapic_version.py | 2 +- .../mapsplatformdatasets_v1/gapic_version.py | 2 +- .../maps_platform_datasets/async_client.py | 80 +- .../services/maps_platform_datasets/client.py | 85 +- .../services/maps_platform_datasets/pagers.py | 32 +- .../maps_platform_datasets/transports/grpc.py | 102 ++- .../transports/grpc_asyncio.py | 101 +- .../maps_platform_datasets/transports/rest.py | 380 +++++++- ...a_google.maps.mapsplatformdatasets.v1.json | 26 +- .../test_maps_platform_datasets.py | 30 + .../google/maps/places/gapic_version.py | 2 +- .../google/maps/places_v1/gapic_version.py | 2 +- .../places_v1/services/places/async_client.py | 72 +- .../maps/places_v1/services/places/client.py | 77 +- .../services/places/transports/grpc.py | 100 +- .../places/transports/grpc_asyncio.py | 99 +- .../services/places/transports/rest.py | 335 ++++++- ...nippet_metadata_google.maps.places.v1.json | 22 +- .../tests/unit/gapic/places_v1/test_places.py | 22 + .../maps/routeoptimization/gapic_version.py | 2 +- .../routeoptimization_v1/gapic_version.py | 2 +- .../route_optimization/async_client.py | 56 +- .../services/route_optimization/client.py | 61 +- .../route_optimization/transports/grpc.py | 100 +- .../transports/grpc_asyncio.py | 97 +- .../route_optimization/transports/rest.py | 203 +++- ...data_google.maps.routeoptimization.v1.json | 10 +- .../test_route_optimization.py | 10 + .../services/routes/async_client.py | 48 +- .../maps/routing_v2/services/routes/client.py | 53 +- .../services/routes/transports/grpc.py | 94 +- .../routes/transports/grpc_asyncio.py | 93 +- .../services/routes/transports/rest.py | 120 ++- ...ippet_metadata_google.maps.routing.v2.json | 8 +- .../unit/gapic/routing_v2/test_routes.py | 8 + .../google/maps/solar/gapic_version.py | 2 +- .../google/maps/solar_v1/gapic_version.py | 2 +- .../solar_v1/services/solar/async_client.py | 56 +- .../maps/solar_v1/services/solar/client.py | 61 +- .../services/solar/transports/grpc.py | 96 +- .../services/solar/transports/grpc_asyncio.py | 95 +- .../services/solar/transports/rest.py | 201 +++- ...snippet_metadata_google.maps.solar.v1.json | 14 +- .../tests/unit/gapic/solar_v1/test_solar.py | 12 + .../merchant_accounts/gapic_version.py | 2 +- .../merchant_accounts_v1beta/gapic_version.py | 2 +- .../account_issue_service/async_client.py | 40 +- .../services/account_issue_service/client.py | 45 +- .../services/account_issue_service/pagers.py | 16 +- .../account_issue_service/transports/grpc.py | 92 +- .../transports/grpc_asyncio.py | 91 +- .../account_issue_service/transports/rest.py | 76 +- .../account_tax_service/async_client.py | 56 +- .../services/account_tax_service/client.py | 61 +- .../services/account_tax_service/pagers.py | 16 +- .../account_tax_service/transports/grpc.py | 96 +- .../transports/grpc_asyncio.py | 95 +- .../account_tax_service/transports/rest.py | 205 ++++- .../services/accounts_service/async_client.py | 80 +- .../services/accounts_service/client.py | 85 +- .../services/accounts_service/pagers.py | 32 +- .../accounts_service/transports/grpc.py | 104 ++- .../transports/grpc_asyncio.py | 103 ++- .../accounts_service/transports/rest.py | 371 +++++++- .../autofeed_settings_service/async_client.py | 48 +- .../autofeed_settings_service/client.py | 53 +- .../transports/grpc.py | 94 +- .../transports/grpc_asyncio.py | 93 +- .../transports/rest.py | 142 ++- .../business_identity_service/async_client.py | 48 +- .../business_identity_service/client.py | 53 +- .../transports/grpc.py | 94 +- .../transports/grpc_asyncio.py | 93 +- .../transports/rest.py | 142 ++- .../business_info_service/async_client.py | 48 +- .../services/business_info_service/client.py | 53 +- .../business_info_service/transports/grpc.py | 94 +- .../transports/grpc_asyncio.py | 93 +- .../business_info_service/transports/rest.py | 138 ++- .../email_preferences_service/async_client.py | 48 +- .../email_preferences_service/client.py | 53 +- .../transports/grpc.py | 94 +- .../transports/grpc_asyncio.py | 93 +- .../transports/rest.py | 142 ++- .../services/homepage_service/async_client.py | 64 +- .../services/homepage_service/client.py | 69 +- .../homepage_service/transports/grpc.py | 98 +- .../transports/grpc_asyncio.py | 97 +- .../homepage_service/transports/rest.py | 264 +++++- .../async_client.py | 48 +- .../online_return_policy_service/client.py | 53 +- .../online_return_policy_service/pagers.py | 16 +- .../transports/grpc.py | 96 +- .../transports/grpc_asyncio.py | 95 +- .../transports/rest.py | 142 ++- .../services/programs_service/async_client.py | 64 +- .../services/programs_service/client.py | 69 +- .../services/programs_service/pagers.py | 16 +- .../programs_service/transports/grpc.py | 98 +- .../transports/grpc_asyncio.py | 97 +- .../programs_service/transports/rest.py | 262 +++++- .../services/regions_service/async_client.py | 72 +- .../services/regions_service/client.py | 77 +- .../services/regions_service/pagers.py | 16 +- .../regions_service/transports/grpc.py | 100 +- .../transports/grpc_asyncio.py | 99 +- .../regions_service/transports/rest.py | 308 ++++++- .../shipping_settings_service/async_client.py | 48 +- .../shipping_settings_service/client.py | 53 +- .../transports/grpc.py | 94 +- .../transports/grpc_asyncio.py | 93 +- .../transports/rest.py | 142 ++- .../async_client.py | 48 +- .../client.py | 53 +- .../transports/grpc.py | 94 +- .../transports/grpc_asyncio.py | 93 +- .../transports/rest.py | 138 ++- .../terms_of_service_service/async_client.py | 56 +- .../terms_of_service_service/client.py | 61 +- .../transports/grpc.py | 96 +- .../transports/grpc_asyncio.py | 95 +- .../transports/rest.py | 180 +++- .../services/user_service/async_client.py | 72 +- .../services/user_service/client.py | 77 +- .../services/user_service/pagers.py | 16 +- .../services/user_service/transports/grpc.py | 100 +- .../user_service/transports/grpc_asyncio.py | 99 +- .../services/user_service/transports/rest.py | 308 ++++++- ...gle.shopping.merchant.accounts.v1beta.json | 182 ++-- .../test_account_issue_service.py | 5 + .../test_account_tax_service.py | 15 + .../test_accounts_service.py | 27 + .../test_autofeed_settings_service.py | 10 + .../test_business_identity_service.py | 10 + .../test_business_info_service.py | 10 + .../test_email_preferences_service.py | 10 + .../test_homepage_service.py | 18 + .../test_online_return_policy_service.py | 10 + .../test_programs_service.py | 20 + .../test_regions_service.py | 25 + .../test_shipping_settings_service.py | 9 + ...erms_of_service_agreement_state_service.py | 10 + .../test_terms_of_service_service.py | 14 + .../test_user_service.py | 25 + .../merchant_conversions/gapic_version.py | 2 +- .../gapic_version.py | 2 +- .../async_client.py | 80 +- .../conversion_sources_service/client.py | 85 +- .../conversion_sources_service/pagers.py | 16 +- .../transports/grpc.py | 104 ++- .../transports/grpc_asyncio.py | 103 ++- .../transports/rest.py | 380 +++++++- ....shopping.merchant.conversions.v1beta.json | 26 +- .../test_conversion_sources_service.py | 29 + .../merchant_datasources/gapic_version.py | 2 +- .../gapic_version.py | 2 +- .../data_sources_service/async_client.py | 80 +- .../services/data_sources_service/client.py | 85 +- .../services/data_sources_service/pagers.py | 16 +- .../data_sources_service/transports/grpc.py | 102 ++- .../transports/grpc_asyncio.py | 101 +- .../data_sources_service/transports/rest.py | 352 ++++++- .../file_uploads_service/async_client.py | 40 +- .../services/file_uploads_service/client.py | 45 +- .../file_uploads_service/transports/grpc.py | 92 +- .../transports/grpc_asyncio.py | 91 +- .../file_uploads_service/transports/rest.py | 74 +- ....shopping.merchant.datasources.v1beta.json | 30 +- .../test_data_sources_service.py | 29 + .../test_file_uploads_service.py | 5 + .../merchant_inventories/gapic_version.py | 2 +- .../gapic_version.py | 2 +- .../local_inventory_service/async_client.py | 56 +- .../local_inventory_service/client.py | 61 +- .../local_inventory_service/pagers.py | 16 +- .../transports/grpc.py | 96 +- .../transports/grpc_asyncio.py | 95 +- .../transports/rest.py | 185 +++- .../async_client.py | 56 +- .../regional_inventory_service/client.py | 61 +- .../regional_inventory_service/pagers.py | 16 +- .../transports/grpc.py | 96 +- .../transports/grpc_asyncio.py | 95 +- .../transports/rest.py | 183 +++- ....shopping.merchant.inventories.v1beta.json | 26 +- .../test_local_inventory_service.py | 14 + .../test_regional_inventory_service.py | 14 + .../shopping/merchant_lfp/gapic_version.py | 2 +- .../merchant_lfp_v1beta/gapic_version.py | 2 +- .../lfp_inventory_service/async_client.py | 40 +- .../services/lfp_inventory_service/client.py | 45 +- .../lfp_inventory_service/transports/grpc.py | 92 +- .../transports/grpc_asyncio.py | 91 +- .../lfp_inventory_service/transports/rest.py | 74 +- .../services/lfp_sale_service/async_client.py | 40 +- .../services/lfp_sale_service/client.py | 45 +- .../lfp_sale_service/transports/grpc.py | 92 +- .../transports/grpc_asyncio.py | 91 +- .../lfp_sale_service/transports/rest.py | 74 +- .../lfp_store_service/async_client.py | 64 +- .../services/lfp_store_service/client.py | 69 +- .../services/lfp_store_service/pagers.py | 16 +- .../lfp_store_service/transports/grpc.py | 98 +- .../transports/grpc_asyncio.py | 97 +- .../lfp_store_service/transports/rest.py | 238 ++++- ...a_google.shopping.merchant.lfp.v1beta.json | 26 +- .../test_lfp_inventory_service.py | 4 + .../test_lfp_sale_service.py | 4 + .../test_lfp_store_service.py | 20 + .../merchant_notifications/gapic_version.py | 2 +- .../gapic_version.py | 2 +- .../notifications_api_service/async_client.py | 72 +- .../notifications_api_service/client.py | 77 +- .../notifications_api_service/pagers.py | 16 +- .../transports/grpc.py | 100 +- .../transports/grpc_asyncio.py | 99 +- .../transports/rest.py | 310 ++++++- ...hopping.merchant.notifications.v1beta.json | 22 +- .../test_notifications_api_service.py | 25 + .../merchant_promotions/gapic_version.py | 2 +- .../gapic_version.py | 2 +- .../promotions_service/async_client.py | 56 +- .../services/promotions_service/client.py | 61 +- .../services/promotions_service/pagers.py | 16 +- .../promotions_service/transports/grpc.py | 96 +- .../transports/grpc_asyncio.py | 95 +- .../promotions_service/transports/rest.py | 202 +++- ...e.shopping.merchant.promotions.v1beta.json | 14 +- .../test_promotions_service.py | 14 + .../shopping/merchant_quota/gapic_version.py | 2 +- .../merchant_quota_v1beta/gapic_version.py | 2 +- .../services/quota_service/async_client.py | 40 +- .../services/quota_service/client.py | 45 +- .../services/quota_service/pagers.py | 16 +- .../services/quota_service/transports/grpc.py | 92 +- .../quota_service/transports/grpc_asyncio.py | 91 +- .../services/quota_service/transports/rest.py | 74 +- ...google.shopping.merchant.quota.v1beta.json | 6 +- .../test_quota_service.py | 5 + .../merchant_reports/gapic_version.py | 2 +- .../merchant_reports_v1beta/gapic_version.py | 2 +- .../services/report_service/async_client.py | 40 +- .../services/report_service/client.py | 45 +- .../services/report_service/pagers.py | 16 +- .../report_service/transports/grpc.py | 92 +- .../report_service/transports/grpc_asyncio.py | 91 +- .../report_service/transports/rest.py | 74 +- ...ogle.shopping.merchant.reports.v1beta.json | 6 +- .../test_report_service.py | 5 + .../grafeas/grafeas/grafeas/gapic_version.py | 2 +- .../grafeas/grafeas_v1/gapic_version.py | 2 +- .../services/grafeas/async_client.py | 144 ++- .../grafeas_v1/services/grafeas/client.py | 122 ++- .../grafeas_v1/services/grafeas/pagers.py | 48 +- .../services/grafeas/transports/grpc.py | 118 ++- .../grafeas/transports/grpc_asyncio.py | 117 ++- .../services/grafeas/transports/rest.py | 866 ++++++++++++++++-- .../snippet_metadata_grafeas.v1.json | 58 +- .../unit/gapic/grafeas_v1/test_grafeas.py | 70 ++ .../unique-grafeas-client.yaml | 27 + 260 files changed, 17135 insertions(+), 2034 deletions(-) diff --git a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets/gapic_version.py b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets/gapic_version.py index aa5666b21197..558c8aab67c5 100644 --- a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets/gapic_version.py +++ b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.4" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/gapic_version.py b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/gapic_version.py index aa5666b21197..558c8aab67c5 100644 --- a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/gapic_version.py +++ b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.4.4" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/async_client.py b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/async_client.py index 515b3f3a7a64..ca22a4331ada 100644 --- a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/async_client.py +++ b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -56,6 +57,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, MapsPlatformDatasetsTransport from .transports.grpc_asyncio import MapsPlatformDatasetsGrpcAsyncIOTransport +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 MapsPlatformDatasetsAsyncClient: """Service definition for the Maps Platform Datasets API.""" @@ -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.maps.mapsplatformdatasets_v1.MapsPlatformDatasetsAsyncClient`.", + extra={ + "serviceName": "google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets", + "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.maps.mapsplatformdatasets.v1.MapsPlatformDatasets", + "credentialsType": None, + }, + ) + async def create_dataset( self, request: Optional[ @@ -275,7 +307,7 @@ async def create_dataset( dataset: Optional[gmm_dataset.Dataset] = 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]]] = (), ) -> gmm_dataset.Dataset: r"""Creates a new dataset for the specified project. @@ -326,8 +358,10 @@ async def sample_create_dataset(): 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.maps.mapsplatformdatasets_v1.types.Dataset: @@ -393,7 +427,7 @@ async def update_dataset_metadata( 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]]] = (), ) -> gmm_dataset.Dataset: r"""Updates the metadata for the dataset. @@ -444,8 +478,10 @@ async def sample_update_dataset_metadata(): 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.maps.mapsplatformdatasets_v1.types.Dataset: @@ -510,7 +546,7 @@ async def get_dataset( 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]]] = (), ) -> dataset.Dataset: r"""Gets the dataset. @@ -561,8 +597,10 @@ async def sample_get_dataset(): 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.maps.mapsplatformdatasets_v1.types.Dataset: @@ -625,7 +663,7 @@ async def fetch_dataset_errors( dataset: 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.FetchDatasetErrorsAsyncPager: r"""Gets all the errors of a dataset. @@ -670,8 +708,10 @@ async def sample_fetch_dataset_errors(): 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.maps.mapsplatformdatasets_v1.services.maps_platform_datasets.pagers.FetchDatasetErrorsAsyncPager: @@ -748,7 +788,7 @@ async def list_datasets( 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.ListDatasetsAsyncPager: r"""Lists all the datasets for the specified project. @@ -794,8 +834,10 @@ async def sample_list_datasets(): 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.maps.mapsplatformdatasets_v1.services.maps_platform_datasets.pagers.ListDatasetsAsyncPager: @@ -872,7 +914,7 @@ async def delete_dataset( 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 the specified dataset. @@ -912,8 +954,10 @@ async def sample_delete_dataset(): 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 diff --git a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/client.py b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/client.py index 91dd506422a4..807d23c116a2 100644 --- a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/client.py +++ b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.protobuf import field_mask_pb2 # type: ignore from google.protobuf import timestamp_pb2 # type: ignore from google.rpc import status_pb2 # type: ignore @@ -584,6 +594,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( @@ -650,6 +664,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.maps.mapsplatformdatasets_v1.MapsPlatformDatasetsClient`.", + extra={ + "serviceName": "google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets", + "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.maps.mapsplatformdatasets.v1.MapsPlatformDatasets", + "credentialsType": None, + }, + ) + def create_dataset( self, request: Optional[ @@ -660,7 +697,7 @@ def create_dataset( dataset: Optional[gmm_dataset.Dataset] = 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]]] = (), ) -> gmm_dataset.Dataset: r"""Creates a new dataset for the specified project. @@ -711,8 +748,10 @@ def sample_create_dataset(): 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.maps.mapsplatformdatasets_v1.types.Dataset: @@ -775,7 +814,7 @@ def update_dataset_metadata( 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]]] = (), ) -> gmm_dataset.Dataset: r"""Updates the metadata for the dataset. @@ -826,8 +865,10 @@ def sample_update_dataset_metadata(): 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.maps.mapsplatformdatasets_v1.types.Dataset: @@ -889,7 +930,7 @@ def get_dataset( 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]]] = (), ) -> dataset.Dataset: r"""Gets the dataset. @@ -940,8 +981,10 @@ def sample_get_dataset(): 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.maps.mapsplatformdatasets_v1.types.Dataset: @@ -1001,7 +1044,7 @@ def fetch_dataset_errors( dataset: 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.FetchDatasetErrorsPager: r"""Gets all the errors of a dataset. @@ -1046,8 +1089,10 @@ def sample_fetch_dataset_errors(): 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.maps.mapsplatformdatasets_v1.services.maps_platform_datasets.pagers.FetchDatasetErrorsPager: @@ -1121,7 +1166,7 @@ def list_datasets( 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.ListDatasetsPager: r"""Lists all the datasets for the specified project. @@ -1167,8 +1212,10 @@ def sample_list_datasets(): 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.maps.mapsplatformdatasets_v1.services.maps_platform_datasets.pagers.ListDatasetsPager: @@ -1242,7 +1289,7 @@ def delete_dataset( 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 the specified dataset. @@ -1282,8 +1329,10 @@ def sample_delete_dataset(): 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 diff --git a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/pagers.py b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/pagers.py index e2bec2262c51..57b61f338411 100644 --- a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/pagers.py +++ b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/pagers.py @@ -69,7 +69,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. @@ -83,8 +83,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 = maps_platform_datasets.FetchDatasetErrorsRequest(request) @@ -145,7 +147,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. @@ -159,8 +161,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 = maps_platform_datasets.FetchDatasetErrorsRequest(request) @@ -225,7 +229,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. @@ -239,8 +243,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 = maps_platform_datasets.ListDatasetsRequest(request) @@ -299,7 +305,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. @@ -313,8 +319,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 = maps_platform_datasets.ListDatasetsRequest(request) diff --git a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/grpc.py b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/grpc.py index 5c0532b541bf..48a7780d1b2e 100644 --- a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/grpc.py +++ b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -21,7 +24,10 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore +import proto # type: ignore from google.maps.mapsplatformdatasets_v1.types import dataset from google.maps.mapsplatformdatasets_v1.types import dataset as gmm_dataset @@ -29,6 +35,81 @@ from .base import DEFAULT_CLIENT_INFO, MapsPlatformDatasetsTransport +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.maps.mapsplatformdatasets.v1.MapsPlatformDatasets", + "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.maps.mapsplatformdatasets.v1.MapsPlatformDatasets", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class MapsPlatformDatasetsGrpcTransport(MapsPlatformDatasetsTransport): """gRPC backend transport for MapsPlatformDatasets. @@ -182,7 +263,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 @@ -256,7 +342,7 @@ def create_dataset( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_dataset" not in self._stubs: - self._stubs["create_dataset"] = self.grpc_channel.unary_unary( + self._stubs["create_dataset"] = self._logged_channel.unary_unary( "/google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets/CreateDataset", request_serializer=maps_platform_datasets.CreateDatasetRequest.serialize, response_deserializer=gmm_dataset.Dataset.deserialize, @@ -284,7 +370,7 @@ def update_dataset_metadata( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_dataset_metadata" not in self._stubs: - self._stubs["update_dataset_metadata"] = self.grpc_channel.unary_unary( + self._stubs["update_dataset_metadata"] = self._logged_channel.unary_unary( "/google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets/UpdateDatasetMetadata", request_serializer=maps_platform_datasets.UpdateDatasetMetadataRequest.serialize, response_deserializer=gmm_dataset.Dataset.deserialize, @@ -310,7 +396,7 @@ def get_dataset( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_dataset" not in self._stubs: - self._stubs["get_dataset"] = self.grpc_channel.unary_unary( + self._stubs["get_dataset"] = self._logged_channel.unary_unary( "/google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets/GetDataset", request_serializer=maps_platform_datasets.GetDatasetRequest.serialize, response_deserializer=dataset.Dataset.deserialize, @@ -339,7 +425,7 @@ def fetch_dataset_errors( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "fetch_dataset_errors" not in self._stubs: - self._stubs["fetch_dataset_errors"] = self.grpc_channel.unary_unary( + self._stubs["fetch_dataset_errors"] = self._logged_channel.unary_unary( "/google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets/FetchDatasetErrors", request_serializer=maps_platform_datasets.FetchDatasetErrorsRequest.serialize, response_deserializer=maps_platform_datasets.FetchDatasetErrorsResponse.deserialize, @@ -368,7 +454,7 @@ def list_datasets( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_datasets" not in self._stubs: - self._stubs["list_datasets"] = self.grpc_channel.unary_unary( + self._stubs["list_datasets"] = self._logged_channel.unary_unary( "/google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets/ListDatasets", request_serializer=maps_platform_datasets.ListDatasetsRequest.serialize, response_deserializer=maps_platform_datasets.ListDatasetsResponse.deserialize, @@ -394,7 +480,7 @@ def delete_dataset( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_dataset" not in self._stubs: - self._stubs["delete_dataset"] = self.grpc_channel.unary_unary( + self._stubs["delete_dataset"] = self._logged_channel.unary_unary( "/google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets/DeleteDataset", request_serializer=maps_platform_datasets.DeleteDatasetRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -402,7 +488,7 @@ def delete_dataset( return self._stubs["delete_dataset"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/grpc_asyncio.py b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/grpc_asyncio.py index cfea955fdf05..54dd547f486f 100644 --- a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/grpc_asyncio.py +++ b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -23,8 +26,11 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.maps.mapsplatformdatasets_v1.types import dataset from google.maps.mapsplatformdatasets_v1.types import dataset as gmm_dataset @@ -33,6 +39,82 @@ from .base import DEFAULT_CLIENT_INFO, MapsPlatformDatasetsTransport from .grpc import MapsPlatformDatasetsGrpcTransport +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.maps.mapsplatformdatasets.v1.MapsPlatformDatasets", + "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.maps.mapsplatformdatasets.v1.MapsPlatformDatasets", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class MapsPlatformDatasetsGrpcAsyncIOTransport(MapsPlatformDatasetsTransport): """gRPC AsyncIO backend transport for MapsPlatformDatasets. @@ -229,10 +311,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 @@ -266,7 +351,7 @@ def create_dataset( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_dataset" not in self._stubs: - self._stubs["create_dataset"] = self.grpc_channel.unary_unary( + self._stubs["create_dataset"] = self._logged_channel.unary_unary( "/google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets/CreateDataset", request_serializer=maps_platform_datasets.CreateDatasetRequest.serialize, response_deserializer=gmm_dataset.Dataset.deserialize, @@ -295,7 +380,7 @@ def update_dataset_metadata( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_dataset_metadata" not in self._stubs: - self._stubs["update_dataset_metadata"] = self.grpc_channel.unary_unary( + self._stubs["update_dataset_metadata"] = self._logged_channel.unary_unary( "/google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets/UpdateDatasetMetadata", request_serializer=maps_platform_datasets.UpdateDatasetMetadataRequest.serialize, response_deserializer=gmm_dataset.Dataset.deserialize, @@ -323,7 +408,7 @@ def get_dataset( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_dataset" not in self._stubs: - self._stubs["get_dataset"] = self.grpc_channel.unary_unary( + self._stubs["get_dataset"] = self._logged_channel.unary_unary( "/google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets/GetDataset", request_serializer=maps_platform_datasets.GetDatasetRequest.serialize, response_deserializer=dataset.Dataset.deserialize, @@ -352,7 +437,7 @@ def fetch_dataset_errors( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "fetch_dataset_errors" not in self._stubs: - self._stubs["fetch_dataset_errors"] = self.grpc_channel.unary_unary( + self._stubs["fetch_dataset_errors"] = self._logged_channel.unary_unary( "/google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets/FetchDatasetErrors", request_serializer=maps_platform_datasets.FetchDatasetErrorsRequest.serialize, response_deserializer=maps_platform_datasets.FetchDatasetErrorsResponse.deserialize, @@ -381,7 +466,7 @@ def list_datasets( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_datasets" not in self._stubs: - self._stubs["list_datasets"] = self.grpc_channel.unary_unary( + self._stubs["list_datasets"] = self._logged_channel.unary_unary( "/google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets/ListDatasets", request_serializer=maps_platform_datasets.ListDatasetsRequest.serialize, response_deserializer=maps_platform_datasets.ListDatasetsResponse.deserialize, @@ -409,7 +494,7 @@ def delete_dataset( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_dataset" not in self._stubs: - self._stubs["delete_dataset"] = self.grpc_channel.unary_unary( + self._stubs["delete_dataset"] = self._logged_channel.unary_unary( "/google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets/DeleteDataset", request_serializer=maps_platform_datasets.DeleteDatasetRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -484,7 +569,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/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/rest.py b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/rest.py index 2264014d5ee6..081d4798e807 100644 --- a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/rest.py +++ b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -40,6 +40,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, @@ -116,8 +124,11 @@ def post_update_dataset_metadata(self, response): def pre_create_dataset( self, request: maps_platform_datasets.CreateDatasetRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[maps_platform_datasets.CreateDatasetRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + maps_platform_datasets.CreateDatasetRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: """Pre-rpc interceptor for create_dataset Override in a subclass to manipulate the request or metadata @@ -137,8 +148,11 @@ def post_create_dataset(self, response: gmm_dataset.Dataset) -> gmm_dataset.Data def pre_delete_dataset( self, request: maps_platform_datasets.DeleteDatasetRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[maps_platform_datasets.DeleteDatasetRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + maps_platform_datasets.DeleteDatasetRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: """Pre-rpc interceptor for delete_dataset Override in a subclass to manipulate the request or metadata @@ -149,9 +163,10 @@ def pre_delete_dataset( def pre_fetch_dataset_errors( self, request: maps_platform_datasets.FetchDatasetErrorsRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - maps_platform_datasets.FetchDatasetErrorsRequest, Sequence[Tuple[str, str]] + maps_platform_datasets.FetchDatasetErrorsRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for fetch_dataset_errors @@ -174,8 +189,11 @@ def post_fetch_dataset_errors( def pre_get_dataset( self, request: maps_platform_datasets.GetDatasetRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[maps_platform_datasets.GetDatasetRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + maps_platform_datasets.GetDatasetRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: """Pre-rpc interceptor for get_dataset Override in a subclass to manipulate the request or metadata @@ -195,8 +213,11 @@ def post_get_dataset(self, response: dataset.Dataset) -> dataset.Dataset: def pre_list_datasets( self, request: maps_platform_datasets.ListDatasetsRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[maps_platform_datasets.ListDatasetsRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + maps_platform_datasets.ListDatasetsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: """Pre-rpc interceptor for list_datasets Override in a subclass to manipulate the request or metadata @@ -218,9 +239,10 @@ def post_list_datasets( def pre_update_dataset_metadata( self, request: maps_platform_datasets.UpdateDatasetMetadataRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - maps_platform_datasets.UpdateDatasetMetadataRequest, Sequence[Tuple[str, str]] + maps_platform_datasets.UpdateDatasetMetadataRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for update_dataset_metadata @@ -363,7 +385,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]]] = (), ) -> gmm_dataset.Dataset: r"""Call the create dataset method over HTTP. @@ -373,8 +395,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: ~.gmm_dataset.Dataset: @@ -386,6 +410,7 @@ def __call__( http_options = ( _BaseMapsPlatformDatasetsRestTransport._BaseCreateDataset._get_http_options() ) + request, metadata = self._interceptor.pre_create_dataset(request, metadata) transcoded_request = _BaseMapsPlatformDatasetsRestTransport._BaseCreateDataset._get_transcoded_request( http_options, request @@ -400,6 +425,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.maps.mapsplatformdatasets_v1.MapsPlatformDatasetsClient.CreateDataset", + extra={ + "serviceName": "google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets", + "rpcName": "CreateDataset", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = MapsPlatformDatasetsRestTransport._CreateDataset._get_response( self._host, @@ -421,7 +473,29 @@ def __call__( pb_resp = gmm_dataset.Dataset.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_dataset(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = gmm_dataset.Dataset.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.maps.mapsplatformdatasets_v1.MapsPlatformDatasetsClient.create_dataset", + extra={ + "serviceName": "google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets", + "rpcName": "CreateDataset", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _DeleteDataset( @@ -459,7 +533,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 dataset method over HTTP. @@ -469,13 +543,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 = ( _BaseMapsPlatformDatasetsRestTransport._BaseDeleteDataset._get_http_options() ) + request, metadata = self._interceptor.pre_delete_dataset(request, metadata) transcoded_request = _BaseMapsPlatformDatasetsRestTransport._BaseDeleteDataset._get_transcoded_request( http_options, request @@ -486,6 +563,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.maps.mapsplatformdatasets_v1.MapsPlatformDatasetsClient.DeleteDataset", + extra={ + "serviceName": "google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets", + "rpcName": "DeleteDataset", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = MapsPlatformDatasetsRestTransport._DeleteDataset._get_response( self._host, @@ -536,7 +640,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]]] = (), ) -> maps_platform_datasets.FetchDatasetErrorsResponse: r"""Call the fetch dataset errors method over HTTP. @@ -547,8 +651,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: ~.maps_platform_datasets.FetchDatasetErrorsResponse: @@ -560,6 +666,7 @@ def __call__( http_options = ( _BaseMapsPlatformDatasetsRestTransport._BaseFetchDatasetErrors._get_http_options() ) + request, metadata = self._interceptor.pre_fetch_dataset_errors( request, metadata ) @@ -572,6 +679,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.maps.mapsplatformdatasets_v1.MapsPlatformDatasetsClient.FetchDatasetErrors", + extra={ + "serviceName": "google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets", + "rpcName": "FetchDatasetErrors", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ( MapsPlatformDatasetsRestTransport._FetchDatasetErrors._get_response( @@ -594,7 +728,33 @@ def __call__( pb_resp = maps_platform_datasets.FetchDatasetErrorsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_fetch_dataset_errors(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + maps_platform_datasets.FetchDatasetErrorsResponse.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.maps.mapsplatformdatasets_v1.MapsPlatformDatasetsClient.fetch_dataset_errors", + extra={ + "serviceName": "google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets", + "rpcName": "FetchDatasetErrors", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _GetDataset( @@ -632,7 +792,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]]] = (), ) -> dataset.Dataset: r"""Call the get dataset method over HTTP. @@ -642,8 +802,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: ~.dataset.Dataset: @@ -655,6 +817,7 @@ def __call__( http_options = ( _BaseMapsPlatformDatasetsRestTransport._BaseGetDataset._get_http_options() ) + request, metadata = self._interceptor.pre_get_dataset(request, metadata) transcoded_request = _BaseMapsPlatformDatasetsRestTransport._BaseGetDataset._get_transcoded_request( http_options, request @@ -665,6 +828,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.maps.mapsplatformdatasets_v1.MapsPlatformDatasetsClient.GetDataset", + extra={ + "serviceName": "google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets", + "rpcName": "GetDataset", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = MapsPlatformDatasetsRestTransport._GetDataset._get_response( self._host, @@ -685,7 +875,29 @@ def __call__( pb_resp = dataset.Dataset.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_dataset(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = dataset.Dataset.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.maps.mapsplatformdatasets_v1.MapsPlatformDatasetsClient.get_dataset", + extra={ + "serviceName": "google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets", + "rpcName": "GetDataset", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListDatasets( @@ -723,7 +935,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]]] = (), ) -> maps_platform_datasets.ListDatasetsResponse: r"""Call the list datasets method over HTTP. @@ -734,8 +946,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: ~.maps_platform_datasets.ListDatasetsResponse: @@ -745,6 +959,7 @@ def __call__( http_options = ( _BaseMapsPlatformDatasetsRestTransport._BaseListDatasets._get_http_options() ) + request, metadata = self._interceptor.pre_list_datasets(request, metadata) transcoded_request = _BaseMapsPlatformDatasetsRestTransport._BaseListDatasets._get_transcoded_request( http_options, request @@ -755,6 +970,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.maps.mapsplatformdatasets_v1.MapsPlatformDatasetsClient.ListDatasets", + extra={ + "serviceName": "google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets", + "rpcName": "ListDatasets", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = MapsPlatformDatasetsRestTransport._ListDatasets._get_response( self._host, @@ -775,7 +1017,31 @@ def __call__( pb_resp = maps_platform_datasets.ListDatasetsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_datasets(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + maps_platform_datasets.ListDatasetsResponse.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.maps.mapsplatformdatasets_v1.MapsPlatformDatasetsClient.list_datasets", + extra={ + "serviceName": "google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets", + "rpcName": "ListDatasets", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _UpdateDatasetMetadata( @@ -814,7 +1080,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]]] = (), ) -> gmm_dataset.Dataset: r"""Call the update dataset metadata method over HTTP. @@ -825,8 +1091,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: ~.gmm_dataset.Dataset: @@ -838,6 +1106,7 @@ def __call__( http_options = ( _BaseMapsPlatformDatasetsRestTransport._BaseUpdateDatasetMetadata._get_http_options() ) + request, metadata = self._interceptor.pre_update_dataset_metadata( request, metadata ) @@ -854,6 +1123,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.maps.mapsplatformdatasets_v1.MapsPlatformDatasetsClient.UpdateDatasetMetadata", + extra={ + "serviceName": "google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets", + "rpcName": "UpdateDatasetMetadata", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ( MapsPlatformDatasetsRestTransport._UpdateDatasetMetadata._get_response( @@ -877,7 +1173,29 @@ def __call__( pb_resp = gmm_dataset.Dataset.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_dataset_metadata(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = gmm_dataset.Dataset.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.maps.mapsplatformdatasets_v1.MapsPlatformDatasetsClient.update_dataset_metadata", + extra={ + "serviceName": "google.maps.mapsplatformdatasets.v1.MapsPlatformDatasets", + "rpcName": "UpdateDatasetMetadata", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-maps-mapsplatformdatasets/samples/generated_samples/snippet_metadata_google.maps.mapsplatformdatasets.v1.json b/packages/google-maps-mapsplatformdatasets/samples/generated_samples/snippet_metadata_google.maps.mapsplatformdatasets.v1.json index 562f762ba0f8..efd05ec97721 100644 --- a/packages/google-maps-mapsplatformdatasets/samples/generated_samples/snippet_metadata_google.maps.mapsplatformdatasets.v1.json +++ b/packages/google-maps-mapsplatformdatasets/samples/generated_samples/snippet_metadata_google.maps.mapsplatformdatasets.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-maps-mapsplatformdatasets", - "version": "0.4.4" + "version": "0.1.0" }, "snippets": [ { @@ -51,7 +51,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.mapsplatformdatasets_v1.types.Dataset", @@ -135,7 +135,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.mapsplatformdatasets_v1.types.Dataset", @@ -216,7 +216,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_dataset" @@ -293,7 +293,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_dataset" @@ -371,7 +371,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.mapsplatformdatasets_v1.services.maps_platform_datasets.pagers.FetchDatasetErrorsAsyncPager", @@ -451,7 +451,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.mapsplatformdatasets_v1.services.maps_platform_datasets.pagers.FetchDatasetErrorsPager", @@ -532,7 +532,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.mapsplatformdatasets_v1.types.Dataset", @@ -612,7 +612,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.mapsplatformdatasets_v1.types.Dataset", @@ -693,7 +693,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.mapsplatformdatasets_v1.services.maps_platform_datasets.pagers.ListDatasetsAsyncPager", @@ -773,7 +773,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.mapsplatformdatasets_v1.services.maps_platform_datasets.pagers.ListDatasetsPager", @@ -858,7 +858,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.mapsplatformdatasets_v1.types.Dataset", @@ -942,7 +942,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.mapsplatformdatasets_v1.types.Dataset", diff --git a/packages/google-maps-mapsplatformdatasets/tests/unit/gapic/mapsplatformdatasets_v1/test_maps_platform_datasets.py b/packages/google-maps-mapsplatformdatasets/tests/unit/gapic/mapsplatformdatasets_v1/test_maps_platform_datasets.py index 1a87f74fd534..60039a8110ef 100644 --- a/packages/google-maps-mapsplatformdatasets/tests/unit/gapic/mapsplatformdatasets_v1/test_maps_platform_datasets.py +++ b/packages/google-maps-mapsplatformdatasets/tests/unit/gapic/mapsplatformdatasets_v1/test_maps_platform_datasets.py @@ -3664,6 +3664,7 @@ def test_create_dataset_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_dataset(request) @@ -3718,6 +3719,7 @@ def test_create_dataset_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_dataset(**mock_args) @@ -3851,6 +3853,7 @@ def test_update_dataset_metadata_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_dataset_metadata(request) @@ -3897,6 +3900,7 @@ def test_update_dataset_metadata_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_dataset_metadata(**mock_args) @@ -4028,6 +4032,7 @@ def test_get_dataset_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_dataset(request) @@ -4073,6 +4078,7 @@ def test_get_dataset_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_dataset(**mock_args) @@ -4215,6 +4221,7 @@ def test_fetch_dataset_errors_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.fetch_dataset_errors(request) @@ -4270,6 +4277,7 @@ def test_fetch_dataset_errors_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.fetch_dataset_errors(**mock_args) @@ -4473,6 +4481,7 @@ def test_list_datasets_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_datasets(request) @@ -4527,6 +4536,7 @@ def test_list_datasets_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_datasets(**mock_args) @@ -4716,6 +4726,7 @@ def test_delete_dataset_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_dataset(request) @@ -4759,6 +4770,7 @@ def test_delete_dataset_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_dataset(**mock_args) @@ -5241,6 +5253,7 @@ def test_create_dataset_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.create_dataset(request) @@ -5362,6 +5375,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_dataset(request) # Establish that the response is the type that we expect. @@ -5407,6 +5421,7 @@ def test_create_dataset_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 = gmm_dataset.Dataset.to_json(gmm_dataset.Dataset()) req.return_value.content = return_value @@ -5451,6 +5466,7 @@ def test_update_dataset_metadata_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_dataset_metadata(request) @@ -5574,6 +5590,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.update_dataset_metadata(request) # Establish that the response is the type that we expect. @@ -5619,6 +5636,7 @@ def test_update_dataset_metadata_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 = gmm_dataset.Dataset.to_json(gmm_dataset.Dataset()) req.return_value.content = return_value @@ -5663,6 +5681,7 @@ def test_get_dataset_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.get_dataset(request) @@ -5703,6 +5722,7 @@ def test_get_dataset_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_dataset(request) # Establish that the response is the type that we expect. @@ -5748,6 +5768,7 @@ def test_get_dataset_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 = dataset.Dataset.to_json(dataset.Dataset()) req.return_value.content = return_value @@ -5792,6 +5813,7 @@ def test_fetch_dataset_errors_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.fetch_dataset_errors(request) @@ -5829,6 +5851,7 @@ def test_fetch_dataset_errors_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.fetch_dataset_errors(request) # Establish that the response is the type that we expect. @@ -5869,6 +5892,7 @@ def test_fetch_dataset_errors_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 = maps_platform_datasets.FetchDatasetErrorsResponse.to_json( maps_platform_datasets.FetchDatasetErrorsResponse() ) @@ -5915,6 +5939,7 @@ def test_list_datasets_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_datasets(request) @@ -5950,6 +5975,7 @@ def test_list_datasets_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_datasets(request) # Establish that the response is the type that we expect. @@ -5990,6 +6016,7 @@ def test_list_datasets_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 = maps_platform_datasets.ListDatasetsResponse.to_json( maps_platform_datasets.ListDatasetsResponse() ) @@ -6036,6 +6063,7 @@ def test_delete_dataset_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_dataset(request) @@ -6066,6 +6094,7 @@ def test_delete_dataset_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_dataset(request) # Establish that the response is the type that we expect. @@ -6102,6 +6131,7 @@ def test_delete_dataset_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 = maps_platform_datasets.DeleteDatasetRequest() metadata = [ diff --git a/packages/google-maps-places/google/maps/places/gapic_version.py b/packages/google-maps-places/google/maps/places/gapic_version.py index e04ba333d337..558c8aab67c5 100644 --- a/packages/google-maps-places/google/maps/places/gapic_version.py +++ b/packages/google-maps-places/google/maps/places/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.20" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-maps-places/google/maps/places_v1/gapic_version.py b/packages/google-maps-places/google/maps/places_v1/gapic_version.py index e04ba333d337..558c8aab67c5 100644 --- a/packages/google-maps-places/google/maps/places_v1/gapic_version.py +++ b/packages/google-maps-places/google/maps/places_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.20" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-maps-places/google/maps/places_v1/services/places/async_client.py b/packages/google-maps-places/google/maps/places_v1/services/places/async_client.py index c402dd58ed47..972568708862 100644 --- a/packages/google-maps-places/google/maps/places_v1/services/places/async_client.py +++ b/packages/google-maps-places/google/maps/places_v1/services/places/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -62,6 +63,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, PlacesTransport from .transports.grpc_asyncio import PlacesGrpcAsyncIOTransport +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 PlacesAsyncClient: """Service definition for the Places API. Note: every request (except @@ -268,13 +278,35 @@ def __init__( client_info=client_info, ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.maps.places_v1.PlacesAsyncClient`.", + extra={ + "serviceName": "google.maps.places.v1.Places", + "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.maps.places.v1.Places", + "credentialsType": None, + }, + ) + async def search_nearby( self, request: Optional[Union[places_service.SearchNearbyRequest, dict]] = 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]]] = (), ) -> places_service.SearchNearbyResponse: r"""Search for places near locations. @@ -313,8 +345,10 @@ async def sample_search_nearby(): 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.maps.places_v1.types.SearchNearbyResponse: @@ -352,7 +386,7 @@ async def search_text( *, 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]]] = (), ) -> places_service.SearchTextResponse: r"""Text query based place search. @@ -388,8 +422,10 @@ async def sample_search_text(): 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.maps.places_v1.types.SearchTextResponse: @@ -428,7 +464,7 @@ async def get_photo_media( 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]]] = (), ) -> places_service.PhotoMedia: r"""Get a photo media with a photo reference string. @@ -479,8 +515,10 @@ async def sample_get_photo_media(): 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.maps.places_v1.types.PhotoMedia: @@ -539,7 +577,7 @@ async def get_place( 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]]] = (), ) -> place.Place: r"""Get the details of a place based on its resource name, which is a string in the ``places/{place_id}`` format. @@ -584,8 +622,10 @@ async def sample_get_place(): 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.maps.places_v1.types.Place: @@ -645,7 +685,7 @@ async def autocomplete_places( *, 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]]] = (), ) -> places_service.AutocompletePlacesResponse: r"""Returns predictions for the given input. @@ -681,8 +721,10 @@ async def sample_autocomplete_places(): 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.maps.places_v1.types.AutocompletePlacesResponse: diff --git a/packages/google-maps-places/google/maps/places_v1/services/places/client.py b/packages/google-maps-places/google/maps/places_v1/services/places/client.py index 6a9591368528..fafc04c6cf36 100644 --- a/packages/google-maps-places/google/maps/places_v1/services/places/client.py +++ b/packages/google-maps-places/google/maps/places_v1/services/places/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.geo.type.types import viewport from google.type import latlng_pb2 # type: ignore from google.type import localized_text_pb2 # type: ignore @@ -640,6 +650,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( @@ -702,13 +716,36 @@ 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.maps.places_v1.PlacesClient`.", + extra={ + "serviceName": "google.maps.places.v1.Places", + "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.maps.places.v1.Places", + "credentialsType": None, + }, + ) + def search_nearby( self, request: Optional[Union[places_service.SearchNearbyRequest, dict]] = 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]]] = (), ) -> places_service.SearchNearbyResponse: r"""Search for places near locations. @@ -747,8 +784,10 @@ def sample_search_nearby(): 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.maps.places_v1.types.SearchNearbyResponse: @@ -784,7 +823,7 @@ def search_text( *, 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]]] = (), ) -> places_service.SearchTextResponse: r"""Text query based place search. @@ -820,8 +859,10 @@ def sample_search_text(): 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.maps.places_v1.types.SearchTextResponse: @@ -858,7 +899,7 @@ def get_photo_media( 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]]] = (), ) -> places_service.PhotoMedia: r"""Get a photo media with a photo reference string. @@ -909,8 +950,10 @@ def sample_get_photo_media(): 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.maps.places_v1.types.PhotoMedia: @@ -966,7 +1009,7 @@ def get_place( 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]]] = (), ) -> place.Place: r"""Get the details of a place based on its resource name, which is a string in the ``places/{place_id}`` format. @@ -1011,8 +1054,10 @@ def sample_get_place(): 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.maps.places_v1.types.Place: @@ -1069,7 +1114,7 @@ def autocomplete_places( *, 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]]] = (), ) -> places_service.AutocompletePlacesResponse: r"""Returns predictions for the given input. @@ -1105,8 +1150,10 @@ def sample_autocomplete_places(): 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.maps.places_v1.types.AutocompletePlacesResponse: diff --git a/packages/google-maps-places/google/maps/places_v1/services/places/transports/grpc.py b/packages/google-maps-places/google/maps/places_v1/services/places/transports/grpc.py index 80a03eb614e9..b4843daefd33 100644 --- a/packages/google-maps-places/google/maps/places_v1/services/places/transports/grpc.py +++ b/packages/google-maps-places/google/maps/places_v1/services/places/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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -20,12 +23,90 @@ 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.maps.places_v1.types import place, places_service from .base import DEFAULT_CLIENT_INFO, PlacesTransport +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.maps.places.v1.Places", + "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.maps.places.v1.Places", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class PlacesGrpcTransport(PlacesTransport): """gRPC backend transport for Places. @@ -183,7 +264,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 @@ -259,7 +345,7 @@ def search_nearby( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "search_nearby" not in self._stubs: - self._stubs["search_nearby"] = self.grpc_channel.unary_unary( + self._stubs["search_nearby"] = self._logged_channel.unary_unary( "/google.maps.places.v1.Places/SearchNearby", request_serializer=places_service.SearchNearbyRequest.serialize, response_deserializer=places_service.SearchNearbyResponse.deserialize, @@ -287,7 +373,7 @@ def search_text( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "search_text" not in self._stubs: - self._stubs["search_text"] = self.grpc_channel.unary_unary( + self._stubs["search_text"] = self._logged_channel.unary_unary( "/google.maps.places.v1.Places/SearchText", request_serializer=places_service.SearchTextRequest.serialize, response_deserializer=places_service.SearchTextResponse.deserialize, @@ -313,7 +399,7 @@ def get_photo_media( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_photo_media" not in self._stubs: - self._stubs["get_photo_media"] = self.grpc_channel.unary_unary( + self._stubs["get_photo_media"] = self._logged_channel.unary_unary( "/google.maps.places.v1.Places/GetPhotoMedia", request_serializer=places_service.GetPhotoMediaRequest.serialize, response_deserializer=places_service.PhotoMedia.deserialize, @@ -338,7 +424,7 @@ def get_place(self) -> Callable[[places_service.GetPlaceRequest], place.Place]: # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_place" not in self._stubs: - self._stubs["get_place"] = self.grpc_channel.unary_unary( + self._stubs["get_place"] = self._logged_channel.unary_unary( "/google.maps.places.v1.Places/GetPlace", request_serializer=places_service.GetPlaceRequest.serialize, response_deserializer=place.Place.deserialize, @@ -367,7 +453,7 @@ def autocomplete_places( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "autocomplete_places" not in self._stubs: - self._stubs["autocomplete_places"] = self.grpc_channel.unary_unary( + self._stubs["autocomplete_places"] = self._logged_channel.unary_unary( "/google.maps.places.v1.Places/AutocompletePlaces", request_serializer=places_service.AutocompletePlacesRequest.serialize, response_deserializer=places_service.AutocompletePlacesResponse.deserialize, @@ -375,7 +461,7 @@ def autocomplete_places( return self._stubs["autocomplete_places"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-maps-places/google/maps/places_v1/services/places/transports/grpc_asyncio.py b/packages/google-maps-places/google/maps/places_v1/services/places/transports/grpc_asyncio.py index 060a9e4f5f0e..3ba7c1d7056b 100644 --- a/packages/google-maps-places/google/maps/places_v1/services/places/transports/grpc_asyncio.py +++ b/packages/google-maps-places/google/maps/places_v1/services/places/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -22,14 +25,93 @@ 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 from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.maps.places_v1.types import place, places_service from .base import DEFAULT_CLIENT_INFO, PlacesTransport from .grpc import PlacesGrpcTransport +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.maps.places.v1.Places", + "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.maps.places.v1.Places", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class PlacesGrpcAsyncIOTransport(PlacesTransport): """gRPC AsyncIO backend transport for Places. @@ -230,10 +312,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 search_nearby( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "search_nearby" not in self._stubs: - self._stubs["search_nearby"] = self.grpc_channel.unary_unary( + self._stubs["search_nearby"] = self._logged_channel.unary_unary( "/google.maps.places.v1.Places/SearchNearby", request_serializer=places_service.SearchNearbyRequest.serialize, response_deserializer=places_service.SearchNearbyResponse.deserialize, @@ -296,7 +381,7 @@ def search_text( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "search_text" not in self._stubs: - self._stubs["search_text"] = self.grpc_channel.unary_unary( + self._stubs["search_text"] = self._logged_channel.unary_unary( "/google.maps.places.v1.Places/SearchText", request_serializer=places_service.SearchTextRequest.serialize, response_deserializer=places_service.SearchTextResponse.deserialize, @@ -324,7 +409,7 @@ def get_photo_media( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_photo_media" not in self._stubs: - self._stubs["get_photo_media"] = self.grpc_channel.unary_unary( + self._stubs["get_photo_media"] = self._logged_channel.unary_unary( "/google.maps.places.v1.Places/GetPhotoMedia", request_serializer=places_service.GetPhotoMediaRequest.serialize, response_deserializer=places_service.PhotoMedia.deserialize, @@ -351,7 +436,7 @@ def get_place( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_place" not in self._stubs: - self._stubs["get_place"] = self.grpc_channel.unary_unary( + self._stubs["get_place"] = self._logged_channel.unary_unary( "/google.maps.places.v1.Places/GetPlace", request_serializer=places_service.GetPlaceRequest.serialize, response_deserializer=place.Place.deserialize, @@ -380,7 +465,7 @@ def autocomplete_places( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "autocomplete_places" not in self._stubs: - self._stubs["autocomplete_places"] = self.grpc_channel.unary_unary( + self._stubs["autocomplete_places"] = self._logged_channel.unary_unary( "/google.maps.places.v1.Places/AutocompletePlaces", request_serializer=places_service.AutocompletePlacesRequest.serialize, response_deserializer=places_service.AutocompletePlacesResponse.deserialize, @@ -423,7 +508,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/packages/google-maps-places/google/maps/places_v1/services/places/transports/rest.py b/packages/google-maps-places/google/maps/places_v1/services/places/transports/rest.py index ffbd77013d0d..141ae8b3f797 100644 --- a/packages/google-maps-places/google/maps/places_v1/services/places/transports/rest.py +++ b/packages/google-maps-places/google/maps/places_v1/services/places/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -37,6 +37,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, @@ -109,8 +117,11 @@ def post_search_text(self, response): def pre_autocomplete_places( self, request: places_service.AutocompletePlacesRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[places_service.AutocompletePlacesRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + places_service.AutocompletePlacesRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: """Pre-rpc interceptor for autocomplete_places Override in a subclass to manipulate the request or metadata @@ -132,8 +143,10 @@ def post_autocomplete_places( def pre_get_photo_media( self, request: places_service.GetPhotoMediaRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[places_service.GetPhotoMediaRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + places_service.GetPhotoMediaRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for get_photo_media Override in a subclass to manipulate the request or metadata @@ -155,8 +168,8 @@ def post_get_photo_media( def pre_get_place( self, request: places_service.GetPlaceRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[places_service.GetPlaceRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[places_service.GetPlaceRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for get_place Override in a subclass to manipulate the request or metadata @@ -176,8 +189,10 @@ def post_get_place(self, response: place.Place) -> place.Place: def pre_search_nearby( self, request: places_service.SearchNearbyRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[places_service.SearchNearbyRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + places_service.SearchNearbyRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for search_nearby Override in a subclass to manipulate the request or metadata @@ -199,8 +214,10 @@ def post_search_nearby( def pre_search_text( self, request: places_service.SearchTextRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[places_service.SearchTextRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + places_service.SearchTextRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for search_text Override in a subclass to manipulate the request or metadata @@ -345,7 +362,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]]] = (), ) -> places_service.AutocompletePlacesResponse: r"""Call the autocomplete places method over HTTP. @@ -355,8 +372,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: ~.places_service.AutocompletePlacesResponse: @@ -368,6 +387,7 @@ def __call__( http_options = ( _BasePlacesRestTransport._BaseAutocompletePlaces._get_http_options() ) + request, metadata = self._interceptor.pre_autocomplete_places( request, metadata ) @@ -388,6 +408,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.maps.places_v1.PlacesClient.AutocompletePlaces", + extra={ + "serviceName": "google.maps.places.v1.Places", + "rpcName": "AutocompletePlaces", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = PlacesRestTransport._AutocompletePlaces._get_response( self._host, @@ -409,7 +456,31 @@ def __call__( pb_resp = places_service.AutocompletePlacesResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_autocomplete_places(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + places_service.AutocompletePlacesResponse.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.maps.places_v1.PlacesClient.autocomplete_places", + extra={ + "serviceName": "google.maps.places.v1.Places", + "rpcName": "AutocompletePlaces", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _GetPhotoMedia(_BasePlacesRestTransport._BaseGetPhotoMedia, PlacesRestStub): @@ -444,7 +515,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]]] = (), ) -> places_service.PhotoMedia: r"""Call the get photo media method over HTTP. @@ -455,8 +526,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: ~.places_service.PhotoMedia: @@ -466,6 +539,7 @@ def __call__( http_options = ( _BasePlacesRestTransport._BaseGetPhotoMedia._get_http_options() ) + request, metadata = self._interceptor.pre_get_photo_media(request, metadata) transcoded_request = ( _BasePlacesRestTransport._BaseGetPhotoMedia._get_transcoded_request( @@ -480,6 +554,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.maps.places_v1.PlacesClient.GetPhotoMedia", + extra={ + "serviceName": "google.maps.places.v1.Places", + "rpcName": "GetPhotoMedia", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = PlacesRestTransport._GetPhotoMedia._get_response( self._host, @@ -500,7 +601,29 @@ def __call__( pb_resp = places_service.PhotoMedia.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_photo_media(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = places_service.PhotoMedia.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.maps.places_v1.PlacesClient.get_photo_media", + extra={ + "serviceName": "google.maps.places.v1.Places", + "rpcName": "GetPhotoMedia", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _GetPlace(_BasePlacesRestTransport._BaseGetPlace, PlacesRestStub): @@ -535,7 +658,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]]] = (), ) -> place.Place: r"""Call the get place method over HTTP. @@ -546,8 +669,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: ~.place.Place: @@ -557,6 +682,7 @@ def __call__( """ http_options = _BasePlacesRestTransport._BaseGetPlace._get_http_options() + request, metadata = self._interceptor.pre_get_place(request, metadata) transcoded_request = ( _BasePlacesRestTransport._BaseGetPlace._get_transcoded_request( @@ -571,6 +697,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.maps.places_v1.PlacesClient.GetPlace", + extra={ + "serviceName": "google.maps.places.v1.Places", + "rpcName": "GetPlace", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = PlacesRestTransport._GetPlace._get_response( self._host, @@ -591,7 +744,29 @@ def __call__( pb_resp = place.Place.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_place(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = place.Place.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.maps.places_v1.PlacesClient.get_place", + extra={ + "serviceName": "google.maps.places.v1.Places", + "rpcName": "GetPlace", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _SearchNearby(_BasePlacesRestTransport._BaseSearchNearby, PlacesRestStub): @@ -627,7 +802,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]]] = (), ) -> places_service.SearchNearbyResponse: r"""Call the search nearby method over HTTP. @@ -637,8 +812,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: ~.places_service.SearchNearbyResponse: @@ -648,6 +825,7 @@ def __call__( http_options = ( _BasePlacesRestTransport._BaseSearchNearby._get_http_options() ) + request, metadata = self._interceptor.pre_search_nearby(request, metadata) transcoded_request = ( _BasePlacesRestTransport._BaseSearchNearby._get_transcoded_request( @@ -666,6 +844,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.maps.places_v1.PlacesClient.SearchNearby", + extra={ + "serviceName": "google.maps.places.v1.Places", + "rpcName": "SearchNearby", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = PlacesRestTransport._SearchNearby._get_response( self._host, @@ -687,7 +892,31 @@ def __call__( pb_resp = places_service.SearchNearbyResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_search_nearby(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = places_service.SearchNearbyResponse.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.maps.places_v1.PlacesClient.search_nearby", + extra={ + "serviceName": "google.maps.places.v1.Places", + "rpcName": "SearchNearby", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _SearchText(_BasePlacesRestTransport._BaseSearchText, PlacesRestStub): @@ -723,7 +952,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]]] = (), ) -> places_service.SearchTextResponse: r"""Call the search text method over HTTP. @@ -733,8 +962,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: ~.places_service.SearchTextResponse: @@ -742,6 +973,7 @@ def __call__( """ http_options = _BasePlacesRestTransport._BaseSearchText._get_http_options() + request, metadata = self._interceptor.pre_search_text(request, metadata) transcoded_request = ( _BasePlacesRestTransport._BaseSearchText._get_transcoded_request( @@ -760,6 +992,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.maps.places_v1.PlacesClient.SearchText", + extra={ + "serviceName": "google.maps.places.v1.Places", + "rpcName": "SearchText", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = PlacesRestTransport._SearchText._get_response( self._host, @@ -781,7 +1040,31 @@ def __call__( pb_resp = places_service.SearchTextResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_search_text(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = places_service.SearchTextResponse.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.maps.places_v1.PlacesClient.search_text", + extra={ + "serviceName": "google.maps.places.v1.Places", + "rpcName": "SearchText", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-maps-places/samples/generated_samples/snippet_metadata_google.maps.places.v1.json b/packages/google-maps-places/samples/generated_samples/snippet_metadata_google.maps.places.v1.json index a07d76715842..bea29a42b294 100644 --- a/packages/google-maps-places/samples/generated_samples/snippet_metadata_google.maps.places.v1.json +++ b/packages/google-maps-places/samples/generated_samples/snippet_metadata_google.maps.places.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-maps-places", - "version": "0.1.20" + "version": "0.1.0" }, "snippets": [ { @@ -43,7 +43,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.places_v1.types.AutocompletePlacesResponse", @@ -119,7 +119,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.places_v1.types.AutocompletePlacesResponse", @@ -200,7 +200,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.places_v1.types.PhotoMedia", @@ -280,7 +280,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.places_v1.types.PhotoMedia", @@ -361,7 +361,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.places_v1.types.Place", @@ -441,7 +441,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.places_v1.types.Place", @@ -518,7 +518,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.places_v1.types.SearchNearbyResponse", @@ -594,7 +594,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.places_v1.types.SearchNearbyResponse", @@ -671,7 +671,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.places_v1.types.SearchTextResponse", @@ -747,7 +747,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.places_v1.types.SearchTextResponse", diff --git a/packages/google-maps-places/tests/unit/gapic/places_v1/test_places.py b/packages/google-maps-places/tests/unit/gapic/places_v1/test_places.py index 2d2d4a4e2fa9..d2290b7fdf33 100644 --- a/packages/google-maps-places/tests/unit/gapic/places_v1/test_places.py +++ b/packages/google-maps-places/tests/unit/gapic/places_v1/test_places.py @@ -2468,6 +2468,7 @@ def test_search_nearby_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.search_nearby(request) @@ -2588,6 +2589,7 @@ def test_search_text_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.search_text(request) @@ -2715,6 +2717,7 @@ def test_get_photo_media_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_photo_media(request) @@ -2769,6 +2772,7 @@ def test_get_photo_media_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_photo_media(**mock_args) @@ -2904,6 +2908,7 @@ def test_get_place_rest_required_fields(request_type=places_service.GetPlaceRequ 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_place(request) @@ -2958,6 +2963,7 @@ def test_get_place_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_place(**mock_args) @@ -3092,6 +3098,7 @@ def test_autocomplete_places_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.autocomplete_places(request) @@ -3537,6 +3544,7 @@ def test_search_nearby_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.search_nearby(request) @@ -3570,6 +3578,7 @@ def test_search_nearby_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.search_nearby(request) # Establish that the response is the type that we expect. @@ -3607,6 +3616,7 @@ def test_search_nearby_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 = places_service.SearchNearbyResponse.to_json( places_service.SearchNearbyResponse() ) @@ -3651,6 +3661,7 @@ def test_search_text_rest_bad_request(request_type=places_service.SearchTextRequ 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.search_text(request) @@ -3684,6 +3695,7 @@ def test_search_text_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.search_text(request) # Establish that the response is the type that we expect. @@ -3721,6 +3733,7 @@ def test_search_text_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 = places_service.SearchTextResponse.to_json( places_service.SearchTextResponse() ) @@ -3767,6 +3780,7 @@ def test_get_photo_media_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.get_photo_media(request) @@ -3803,6 +3817,7 @@ def test_get_photo_media_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_photo_media(request) # Establish that the response is the type that we expect. @@ -3842,6 +3857,7 @@ def test_get_photo_media_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 = places_service.PhotoMedia.to_json(places_service.PhotoMedia()) req.return_value.content = return_value @@ -3884,6 +3900,7 @@ def test_get_place_rest_bad_request(request_type=places_service.GetPlaceRequest) 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_place(request) @@ -3960,6 +3977,7 @@ def test_get_place_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_place(request) # Establish that the response is the type that we expect. @@ -4037,6 +4055,7 @@ def test_get_place_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 = place.Place.to_json(place.Place()) req.return_value.content = return_value @@ -4081,6 +4100,7 @@ def test_autocomplete_places_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.autocomplete_places(request) @@ -4114,6 +4134,7 @@ def test_autocomplete_places_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.autocomplete_places(request) # Establish that the response is the type that we expect. @@ -4151,6 +4172,7 @@ def test_autocomplete_places_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 = places_service.AutocompletePlacesResponse.to_json( places_service.AutocompletePlacesResponse() ) diff --git a/packages/google-maps-routeoptimization/google/maps/routeoptimization/gapic_version.py b/packages/google-maps-routeoptimization/google/maps/routeoptimization/gapic_version.py index 51d2795b9d6b..558c8aab67c5 100644 --- a/packages/google-maps-routeoptimization/google/maps/routeoptimization/gapic_version.py +++ b/packages/google-maps-routeoptimization/google/maps/routeoptimization/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.6" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/gapic_version.py b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/gapic_version.py index 51d2795b9d6b..558c8aab67c5 100644 --- a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/gapic_version.py +++ b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.6" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/async_client.py b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/async_client.py index d8ad78e46e99..4c42252bdb67 100644 --- a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/async_client.py +++ b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -52,6 +53,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, RouteOptimizationTransport from .transports.grpc_asyncio import RouteOptimizationGrpcAsyncIOTransport +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 RouteOptimizationAsyncClient: """A service for optimizing vehicle tours. @@ -282,6 +292,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.maps.routeoptimization_v1.RouteOptimizationAsyncClient`.", + extra={ + "serviceName": "google.maps.routeoptimization.v1.RouteOptimization", + "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.maps.routeoptimization.v1.RouteOptimization", + "credentialsType": None, + }, + ) + async def optimize_tours( self, request: Optional[ @@ -290,7 +322,7 @@ async def optimize_tours( *, 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]]] = (), ) -> route_optimization_service.OptimizeToursResponse: r"""Sends an ``OptimizeToursRequest`` containing a ``ShipmentModel`` and returns an ``OptimizeToursResponse`` containing @@ -344,8 +376,10 @@ async def sample_optimize_tours(): 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.maps.routeoptimization_v1.types.OptimizeToursResponse: @@ -396,7 +430,7 @@ async def batch_optimize_tours( *, 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]]] = (), ) -> operation_async.AsyncOperation: r"""Optimizes vehicle tours for one or more ``OptimizeToursRequest`` messages as a batch. @@ -473,8 +507,10 @@ async def sample_batch_optimize_tours(): 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.api_core.operation_async.AsyncOperation: @@ -533,7 +569,7 @@ async def get_operation( *, 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]]] = (), ) -> operations_pb2.Operation: r"""Gets the latest state of a long-running operation. @@ -544,8 +580,10 @@ async def get_operation( 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: ~.operations_pb2.Operation: An ``Operation`` object. diff --git a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/client.py b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/client.py index 8f8dce2da47c..6d57e2ba7255 100644 --- a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/client.py +++ b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore from google.longrunning import operations_pb2 # type: ignore @@ -586,6 +596,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( @@ -652,6 +666,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.maps.routeoptimization_v1.RouteOptimizationClient`.", + extra={ + "serviceName": "google.maps.routeoptimization.v1.RouteOptimization", + "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.maps.routeoptimization.v1.RouteOptimization", + "credentialsType": None, + }, + ) + def optimize_tours( self, request: Optional[ @@ -660,7 +697,7 @@ def optimize_tours( *, 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]]] = (), ) -> route_optimization_service.OptimizeToursResponse: r"""Sends an ``OptimizeToursRequest`` containing a ``ShipmentModel`` and returns an ``OptimizeToursResponse`` containing @@ -714,8 +751,10 @@ def sample_optimize_tours(): 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.maps.routeoptimization_v1.types.OptimizeToursResponse: @@ -764,7 +803,7 @@ def batch_optimize_tours( *, 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]]] = (), ) -> operation.Operation: r"""Optimizes vehicle tours for one or more ``OptimizeToursRequest`` messages as a batch. @@ -841,8 +880,10 @@ def sample_batch_optimize_tours(): 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.api_core.operation.Operation: @@ -912,7 +953,7 @@ def get_operation( *, 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]]] = (), ) -> operations_pb2.Operation: r"""Gets the latest state of a long-running operation. @@ -923,8 +964,10 @@ def get_operation( 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: ~.operations_pb2.Operation: An ``Operation`` object. diff --git a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/grpc.py b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/grpc.py index 79f73aece6fa..7607e1eacc51 100644 --- a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/grpc.py +++ b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -21,12 +24,90 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.longrunning import operations_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore +import proto # type: ignore from google.maps.routeoptimization_v1.types import route_optimization_service from .base import DEFAULT_CLIENT_INFO, RouteOptimizationTransport +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.maps.routeoptimization.v1.RouteOptimization", + "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.maps.routeoptimization.v1.RouteOptimization", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class RouteOptimizationGrpcTransport(RouteOptimizationTransport): """gRPC backend transport for RouteOptimization. @@ -203,7 +284,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 @@ -267,7 +353,9 @@ def operations_client(self) -> operations_v1.OperationsClient: """ # Quick check: Only create a new client if we do not already have one. if self._operations_client is None: - self._operations_client = operations_v1.OperationsClient(self.grpc_channel) + self._operations_client = operations_v1.OperationsClient( + self._logged_channel + ) # Return the client from cache. return self._operations_client @@ -309,7 +397,7 @@ def optimize_tours( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "optimize_tours" not in self._stubs: - self._stubs["optimize_tours"] = self.grpc_channel.unary_unary( + self._stubs["optimize_tours"] = self._logged_channel.unary_unary( "/google.maps.routeoptimization.v1.RouteOptimization/OptimizeTours", request_serializer=route_optimization_service.OptimizeToursRequest.serialize, response_deserializer=route_optimization_service.OptimizeToursResponse.deserialize, @@ -361,7 +449,7 @@ def batch_optimize_tours( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "batch_optimize_tours" not in self._stubs: - self._stubs["batch_optimize_tours"] = self.grpc_channel.unary_unary( + self._stubs["batch_optimize_tours"] = self._logged_channel.unary_unary( "/google.maps.routeoptimization.v1.RouteOptimization/BatchOptimizeTours", request_serializer=route_optimization_service.BatchOptimizeToursRequest.serialize, response_deserializer=operations_pb2.Operation.FromString, @@ -369,7 +457,7 @@ def batch_optimize_tours( return self._stubs["batch_optimize_tours"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def get_operation( @@ -381,7 +469,7 @@ def get_operation( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_operation" not in self._stubs: - self._stubs["get_operation"] = self.grpc_channel.unary_unary( + self._stubs["get_operation"] = self._logged_channel.unary_unary( "/google.longrunning.Operations/GetOperation", request_serializer=operations_pb2.GetOperationRequest.SerializeToString, response_deserializer=operations_pb2.Operation.FromString, diff --git a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/grpc_asyncio.py b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/grpc_asyncio.py index 36b86ca20bae..faef6ce0f04b 100644 --- a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/grpc_asyncio.py +++ b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -23,14 +26,93 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.longrunning import operations_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.maps.routeoptimization_v1.types import route_optimization_service from .base import DEFAULT_CLIENT_INFO, RouteOptimizationTransport from .grpc import RouteOptimizationGrpcTransport +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.maps.routeoptimization.v1.RouteOptimization", + "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.maps.routeoptimization.v1.RouteOptimization", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class RouteOptimizationGrpcAsyncIOTransport(RouteOptimizationTransport): """gRPC AsyncIO backend transport for RouteOptimization. @@ -250,10 +332,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 @@ -276,7 +361,7 @@ def operations_client(self) -> operations_v1.OperationsAsyncClient: # Quick check: Only create a new client if we do not already have one. if self._operations_client is None: self._operations_client = operations_v1.OperationsAsyncClient( - self.grpc_channel + self._logged_channel ) # Return the client from cache. @@ -319,7 +404,7 @@ def optimize_tours( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "optimize_tours" not in self._stubs: - self._stubs["optimize_tours"] = self.grpc_channel.unary_unary( + self._stubs["optimize_tours"] = self._logged_channel.unary_unary( "/google.maps.routeoptimization.v1.RouteOptimization/OptimizeTours", request_serializer=route_optimization_service.OptimizeToursRequest.serialize, response_deserializer=route_optimization_service.OptimizeToursResponse.deserialize, @@ -372,7 +457,7 @@ def batch_optimize_tours( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "batch_optimize_tours" not in self._stubs: - self._stubs["batch_optimize_tours"] = self.grpc_channel.unary_unary( + self._stubs["batch_optimize_tours"] = self._logged_channel.unary_unary( "/google.maps.routeoptimization.v1.RouteOptimization/BatchOptimizeTours", request_serializer=route_optimization_service.BatchOptimizeToursRequest.serialize, response_deserializer=operations_pb2.Operation.FromString, @@ -414,7 +499,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: @@ -430,7 +515,7 @@ def get_operation( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_operation" not in self._stubs: - self._stubs["get_operation"] = self.grpc_channel.unary_unary( + self._stubs["get_operation"] = self._logged_channel.unary_unary( "/google.longrunning.Operations/GetOperation", request_serializer=operations_pb2.GetOperationRequest.SerializeToString, response_deserializer=operations_pb2.Operation.FromString, diff --git a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/rest.py b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/rest.py index ab439b3fef3b..c5c585833fc9 100644 --- a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/rest.py +++ b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -38,6 +38,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, @@ -86,9 +94,10 @@ def post_optimize_tours(self, response): def pre_batch_optimize_tours( self, request: route_optimization_service.BatchOptimizeToursRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - route_optimization_service.BatchOptimizeToursRequest, Sequence[Tuple[str, str]] + route_optimization_service.BatchOptimizeToursRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for batch_optimize_tours @@ -111,9 +120,10 @@ def post_batch_optimize_tours( def pre_optimize_tours( self, request: route_optimization_service.OptimizeToursRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - route_optimization_service.OptimizeToursRequest, Sequence[Tuple[str, str]] + route_optimization_service.OptimizeToursRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for optimize_tours @@ -136,8 +146,10 @@ def post_optimize_tours( def pre_get_operation( self, request: operations_pb2.GetOperationRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for get_operation Override in a subclass to manipulate the request or metadata @@ -336,7 +348,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]]] = (), ) -> operations_pb2.Operation: r"""Call the batch optimize tours method over HTTP. @@ -352,8 +364,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: ~.operations_pb2.Operation: @@ -366,6 +380,7 @@ def __call__( http_options = ( _BaseRouteOptimizationRestTransport._BaseBatchOptimizeTours._get_http_options() ) + request, metadata = self._interceptor.pre_batch_optimize_tours( request, metadata ) @@ -382,6 +397,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.maps.routeoptimization_v1.RouteOptimizationClient.BatchOptimizeTours", + extra={ + "serviceName": "google.maps.routeoptimization.v1.RouteOptimization", + "rpcName": "BatchOptimizeTours", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = RouteOptimizationRestTransport._BatchOptimizeTours._get_response( self._host, @@ -401,7 +443,29 @@ def __call__( # Return the response resp = operations_pb2.Operation() json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_batch_optimize_tours(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.maps.routeoptimization_v1.RouteOptimizationClient.batch_optimize_tours", + extra={ + "serviceName": "google.maps.routeoptimization.v1.RouteOptimization", + "rpcName": "BatchOptimizeTours", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _OptimizeTours( @@ -440,7 +504,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]]] = (), ) -> route_optimization_service.OptimizeToursResponse: r"""Call the optimize tours method over HTTP. @@ -453,8 +517,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: ~.route_optimization_service.OptimizeToursResponse: @@ -469,6 +535,7 @@ def __call__( http_options = ( _BaseRouteOptimizationRestTransport._BaseOptimizeTours._get_http_options() ) + request, metadata = self._interceptor.pre_optimize_tours(request, metadata) transcoded_request = _BaseRouteOptimizationRestTransport._BaseOptimizeTours._get_transcoded_request( http_options, request @@ -483,6 +550,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.maps.routeoptimization_v1.RouteOptimizationClient.OptimizeTours", + extra={ + "serviceName": "google.maps.routeoptimization.v1.RouteOptimization", + "rpcName": "OptimizeTours", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = RouteOptimizationRestTransport._OptimizeTours._get_response( self._host, @@ -504,7 +598,33 @@ def __call__( pb_resp = route_optimization_service.OptimizeToursResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_optimize_tours(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + route_optimization_service.OptimizeToursResponse.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.maps.routeoptimization_v1.RouteOptimizationClient.optimize_tours", + extra={ + "serviceName": "google.maps.routeoptimization.v1.RouteOptimization", + "rpcName": "OptimizeTours", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property @@ -566,7 +686,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]]] = (), ) -> operations_pb2.Operation: r"""Call the get operation method over HTTP. @@ -576,8 +696,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: operations_pb2.Operation: Response from GetOperation method. @@ -586,6 +708,7 @@ def __call__( http_options = ( _BaseRouteOptimizationRestTransport._BaseGetOperation._get_http_options() ) + request, metadata = self._interceptor.pre_get_operation(request, metadata) transcoded_request = _BaseRouteOptimizationRestTransport._BaseGetOperation._get_transcoded_request( http_options, request @@ -596,6 +719,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.maps.routeoptimization_v1.RouteOptimizationClient.GetOperation", + extra={ + "serviceName": "google.maps.routeoptimization.v1.RouteOptimization", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = RouteOptimizationRestTransport._GetOperation._get_response( self._host, @@ -615,6 +765,27 @@ def __call__( resp = operations_pb2.Operation() resp = json_format.Parse(content, resp) resp = self._interceptor.post_get_operation(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.maps.routeoptimization_v1.RouteOptimizationAsyncClient.GetOperation", + extra={ + "serviceName": "google.maps.routeoptimization.v1.RouteOptimization", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) return resp @property diff --git a/packages/google-maps-routeoptimization/samples/generated_samples/snippet_metadata_google.maps.routeoptimization.v1.json b/packages/google-maps-routeoptimization/samples/generated_samples/snippet_metadata_google.maps.routeoptimization.v1.json index 16fb1d76800a..fcfcf65d2f4f 100644 --- a/packages/google-maps-routeoptimization/samples/generated_samples/snippet_metadata_google.maps.routeoptimization.v1.json +++ b/packages/google-maps-routeoptimization/samples/generated_samples/snippet_metadata_google.maps.routeoptimization.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-maps-routeoptimization", - "version": "0.1.6" + "version": "0.1.0" }, "snippets": [ { @@ -43,7 +43,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.api_core.operation_async.AsyncOperation", @@ -119,7 +119,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.api_core.operation.Operation", @@ -196,7 +196,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.routeoptimization_v1.types.OptimizeToursResponse", @@ -272,7 +272,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.routeoptimization_v1.types.OptimizeToursResponse", diff --git a/packages/google-maps-routeoptimization/tests/unit/gapic/routeoptimization_v1/test_route_optimization.py b/packages/google-maps-routeoptimization/tests/unit/gapic/routeoptimization_v1/test_route_optimization.py index 875a89bb1e67..c8817288cd0e 100644 --- a/packages/google-maps-routeoptimization/tests/unit/gapic/routeoptimization_v1/test_route_optimization.py +++ b/packages/google-maps-routeoptimization/tests/unit/gapic/routeoptimization_v1/test_route_optimization.py @@ -1719,6 +1719,7 @@ def test_optimize_tours_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.optimize_tours(request) @@ -1844,6 +1845,7 @@ def test_batch_optimize_tours_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.batch_optimize_tours(request) @@ -2115,6 +2117,7 @@ def test_optimize_tours_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.optimize_tours(request) @@ -2150,6 +2153,7 @@ def test_optimize_tours_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.optimize_tours(request) # Establish that the response is the type that we expect. @@ -2190,6 +2194,7 @@ def test_optimize_tours_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 = route_optimization_service.OptimizeToursResponse.to_json( route_optimization_service.OptimizeToursResponse() ) @@ -2236,6 +2241,7 @@ def test_batch_optimize_tours_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.batch_optimize_tours(request) @@ -2266,6 +2272,7 @@ def test_batch_optimize_tours_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.batch_optimize_tours(request) # Establish that the response is the type that we expect. @@ -2307,6 +2314,7 @@ def test_batch_optimize_tours_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 = json_format.MessageToJson(operations_pb2.Operation()) req.return_value.content = return_value @@ -2353,6 +2361,7 @@ def test_get_operation_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_operation(request) @@ -2383,6 +2392,7 @@ def test_get_operation_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_operation(request) diff --git a/packages/google-maps-routing/google/maps/routing_v2/services/routes/async_client.py b/packages/google-maps-routing/google/maps/routing_v2/services/routes/async_client.py index a6882615fc53..a060eb0bcd7d 100644 --- a/packages/google-maps-routing/google/maps/routing_v2/services/routes/async_client.py +++ b/packages/google-maps-routing/google/maps/routing_v2/services/routes/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( AsyncIterable, @@ -58,6 +59,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, RoutesTransport from .transports.grpc_asyncio import RoutesGrpcAsyncIOTransport +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 RoutesAsyncClient: """The Routes API.""" @@ -251,13 +261,35 @@ def __init__( client_info=client_info, ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.maps.routing_v2.RoutesAsyncClient`.", + extra={ + "serviceName": "google.maps.routing.v2.Routes", + "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.maps.routing.v2.Routes", + "credentialsType": None, + }, + ) + async def compute_routes( self, request: Optional[Union[routes_service.ComputeRoutesRequest, dict]] = 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]]] = (), ) -> routes_service.ComputeRoutesResponse: r"""Returns the primary route along with optional alternate routes, given a set of terminal and intermediate waypoints. @@ -328,8 +360,10 @@ async def sample_compute_routes(): 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.maps.routing_v2.types.ComputeRoutesResponse: @@ -367,7 +401,7 @@ def compute_route_matrix( *, 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[routes_service.RouteMatrixElement]]: r"""Takes in a list of origins and destinations and returns a stream containing route information for each combination of origin and @@ -440,8 +474,10 @@ async def sample_compute_route_matrix(): 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.maps.routing_v2.types.RouteMatrixElement]: diff --git a/packages/google-maps-routing/google/maps/routing_v2/services/routes/client.py b/packages/google-maps-routing/google/maps/routing_v2/services/routes/client.py index f190526e7f87..71cdfe6b5391 100644 --- a/packages/google-maps-routing/google/maps/routing_v2/services/routes/client.py +++ b/packages/google-maps-routing/google/maps/routing_v2/services/routes/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -49,6 +50,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.protobuf import duration_pb2 # type: ignore from google.rpc import status_pb2 # type: ignore @@ -562,6 +572,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( @@ -624,13 +638,36 @@ 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.maps.routing_v2.RoutesClient`.", + extra={ + "serviceName": "google.maps.routing.v2.Routes", + "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.maps.routing.v2.Routes", + "credentialsType": None, + }, + ) + def compute_routes( self, request: Optional[Union[routes_service.ComputeRoutesRequest, dict]] = 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]]] = (), ) -> routes_service.ComputeRoutesResponse: r"""Returns the primary route along with optional alternate routes, given a set of terminal and intermediate waypoints. @@ -701,8 +738,10 @@ def sample_compute_routes(): 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.maps.routing_v2.types.ComputeRoutesResponse: @@ -738,7 +777,7 @@ def compute_route_matrix( *, 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[routes_service.RouteMatrixElement]: r"""Takes in a list of origins and destinations and returns a stream containing route information for each combination of origin and @@ -811,8 +850,10 @@ def sample_compute_route_matrix(): 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.maps.routing_v2.types.RouteMatrixElement]: diff --git a/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/grpc.py b/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/grpc.py index c2b9f751e312..11ba4ec58540 100644 --- a/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/grpc.py +++ b/packages/google-maps-routing/google/maps/routing_v2/services/routes/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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -20,12 +23,90 @@ 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.maps.routing_v2.types import routes_service from .base import DEFAULT_CLIENT_INFO, RoutesTransport +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.maps.routing.v2.Routes", + "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.maps.routing.v2.Routes", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class RoutesGrpcTransport(RoutesTransport): """gRPC backend transport for Routes. @@ -179,7 +260,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 @@ -291,7 +377,7 @@ def compute_routes( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "compute_routes" not in self._stubs: - self._stubs["compute_routes"] = self.grpc_channel.unary_unary( + self._stubs["compute_routes"] = self._logged_channel.unary_unary( "/google.maps.routing.v2.Routes/ComputeRoutes", request_serializer=routes_service.ComputeRoutesRequest.serialize, response_deserializer=routes_service.ComputeRoutesResponse.deserialize, @@ -356,7 +442,7 @@ def compute_route_matrix( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "compute_route_matrix" not in self._stubs: - self._stubs["compute_route_matrix"] = self.grpc_channel.unary_stream( + self._stubs["compute_route_matrix"] = self._logged_channel.unary_stream( "/google.maps.routing.v2.Routes/ComputeRouteMatrix", request_serializer=routes_service.ComputeRouteMatrixRequest.serialize, response_deserializer=routes_service.RouteMatrixElement.deserialize, @@ -364,7 +450,7 @@ def compute_route_matrix( return self._stubs["compute_route_matrix"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/grpc_asyncio.py b/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/grpc_asyncio.py index 53f4300794cc..fb7a0daa133b 100644 --- a/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/grpc_asyncio.py +++ b/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -22,14 +25,93 @@ 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 from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.maps.routing_v2.types import routes_service from .base import DEFAULT_CLIENT_INFO, RoutesTransport from .grpc import RoutesGrpcTransport +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.maps.routing.v2.Routes", + "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.maps.routing.v2.Routes", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class RoutesGrpcAsyncIOTransport(RoutesTransport): """gRPC AsyncIO backend transport for Routes. @@ -226,10 +308,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 @@ -300,7 +385,7 @@ def compute_routes( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "compute_routes" not in self._stubs: - self._stubs["compute_routes"] = self.grpc_channel.unary_unary( + self._stubs["compute_routes"] = self._logged_channel.unary_unary( "/google.maps.routing.v2.Routes/ComputeRoutes", request_serializer=routes_service.ComputeRoutesRequest.serialize, response_deserializer=routes_service.ComputeRoutesResponse.deserialize, @@ -366,7 +451,7 @@ def compute_route_matrix( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "compute_route_matrix" not in self._stubs: - self._stubs["compute_route_matrix"] = self.grpc_channel.unary_stream( + self._stubs["compute_route_matrix"] = self._logged_channel.unary_stream( "/google.maps.routing.v2.Routes/ComputeRouteMatrix", request_serializer=routes_service.ComputeRouteMatrixRequest.serialize, response_deserializer=routes_service.RouteMatrixElement.deserialize, @@ -394,7 +479,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/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/rest.py b/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/rest.py index 7228185de516..e3209c8e05df 100644 --- a/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/rest.py +++ b/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -37,6 +37,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, @@ -85,8 +93,11 @@ def post_compute_routes(self, response): def pre_compute_route_matrix( self, request: routes_service.ComputeRouteMatrixRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[routes_service.ComputeRouteMatrixRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + routes_service.ComputeRouteMatrixRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: """Pre-rpc interceptor for compute_route_matrix Override in a subclass to manipulate the request or metadata @@ -108,8 +119,10 @@ def post_compute_route_matrix( def pre_compute_routes( self, request: routes_service.ComputeRoutesRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[routes_service.ComputeRoutesRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + routes_service.ComputeRoutesRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for compute_routes Override in a subclass to manipulate the request or metadata @@ -251,7 +264,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: r"""Call the compute route matrix method over HTTP. @@ -261,8 +274,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: ~.routes_service.RouteMatrixElement: @@ -276,6 +291,7 @@ def __call__( http_options = ( _BaseRoutesRestTransport._BaseComputeRouteMatrix._get_http_options() ) + request, metadata = self._interceptor.pre_compute_route_matrix( request, metadata ) @@ -296,6 +312,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.maps.routing_v2.RoutesClient.ComputeRouteMatrix", + extra={ + "serviceName": "google.maps.routing.v2.Routes", + "rpcName": "ComputeRouteMatrix", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = RoutesRestTransport._ComputeRouteMatrix._get_response( self._host, @@ -316,6 +359,7 @@ def __call__( resp = rest_streaming.ResponseIterator( response, routes_service.RouteMatrixElement ) + resp = self._interceptor.post_compute_route_matrix(resp) return resp @@ -352,7 +396,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]]] = (), ) -> routes_service.ComputeRoutesResponse: r"""Call the compute routes method over HTTP. @@ -362,8 +406,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: ~.routes_service.ComputeRoutesResponse: @@ -373,6 +419,7 @@ def __call__( http_options = ( _BaseRoutesRestTransport._BaseComputeRoutes._get_http_options() ) + request, metadata = self._interceptor.pre_compute_routes(request, metadata) transcoded_request = ( _BaseRoutesRestTransport._BaseComputeRoutes._get_transcoded_request( @@ -391,6 +438,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.maps.routing_v2.RoutesClient.ComputeRoutes", + extra={ + "serviceName": "google.maps.routing.v2.Routes", + "rpcName": "ComputeRoutes", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = RoutesRestTransport._ComputeRoutes._get_response( self._host, @@ -412,7 +486,31 @@ def __call__( pb_resp = routes_service.ComputeRoutesResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_compute_routes(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = routes_service.ComputeRoutesResponse.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.maps.routing_v2.RoutesClient.compute_routes", + extra={ + "serviceName": "google.maps.routing.v2.Routes", + "rpcName": "ComputeRoutes", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-maps-routing/samples/generated_samples/snippet_metadata_google.maps.routing.v2.json b/packages/google-maps-routing/samples/generated_samples/snippet_metadata_google.maps.routing.v2.json index b5ed5aca319c..ebb0fa3e0c00 100644 --- a/packages/google-maps-routing/samples/generated_samples/snippet_metadata_google.maps.routing.v2.json +++ b/packages/google-maps-routing/samples/generated_samples/snippet_metadata_google.maps.routing.v2.json @@ -43,7 +43,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "Iterable[google.maps.routing_v2.types.RouteMatrixElement]", @@ -119,7 +119,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "Iterable[google.maps.routing_v2.types.RouteMatrixElement]", @@ -196,7 +196,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.routing_v2.types.ComputeRoutesResponse", @@ -272,7 +272,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.routing_v2.types.ComputeRoutesResponse", diff --git a/packages/google-maps-routing/tests/unit/gapic/routing_v2/test_routes.py b/packages/google-maps-routing/tests/unit/gapic/routing_v2/test_routes.py index 4f52fcf75276..133a7dcd7615 100644 --- a/packages/google-maps-routing/tests/unit/gapic/routing_v2/test_routes.py +++ b/packages/google-maps-routing/tests/unit/gapic/routing_v2/test_routes.py @@ -1477,6 +1477,7 @@ def test_compute_routes_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.compute_routes(request) @@ -1605,6 +1606,7 @@ def test_compute_route_matrix_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"} with mock.patch.object(response_value, "iter_content") as iter_content: iter_content.return_value = iter(json_return_value) @@ -1877,6 +1879,7 @@ def test_compute_routes_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.compute_routes(request) @@ -1910,6 +1913,7 @@ def test_compute_routes_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.compute_routes(request) # Establish that the response is the type that we expect. @@ -1947,6 +1951,7 @@ def test_compute_routes_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 = routes_service.ComputeRoutesResponse.to_json( routes_service.ComputeRoutesResponse() ) @@ -1993,6 +1998,7 @@ def test_compute_route_matrix_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.compute_route_matrix(request) @@ -2032,6 +2038,7 @@ def test_compute_route_matrix_rest_call_success(request_type): json_return_value = "[{}]".format(json_return_value) response_value.iter_content = mock.Mock(return_value=iter(json_return_value)) req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} response = client.compute_route_matrix(request) assert isinstance(response, Iterable) @@ -2076,6 +2083,7 @@ def test_compute_route_matrix_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 = routes_service.RouteMatrixElement.to_json( routes_service.RouteMatrixElement() ) diff --git a/packages/google-maps-solar/google/maps/solar/gapic_version.py b/packages/google-maps-solar/google/maps/solar/gapic_version.py index 937ede8823ef..558c8aab67c5 100644 --- a/packages/google-maps-solar/google/maps/solar/gapic_version.py +++ b/packages/google-maps-solar/google/maps/solar/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.4" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-maps-solar/google/maps/solar_v1/gapic_version.py b/packages/google-maps-solar/google/maps/solar_v1/gapic_version.py index 937ede8823ef..558c8aab67c5 100644 --- a/packages/google-maps-solar/google/maps/solar_v1/gapic_version.py +++ b/packages/google-maps-solar/google/maps/solar_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.4" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-maps-solar/google/maps/solar_v1/services/solar/async_client.py b/packages/google-maps-solar/google/maps/solar_v1/services/solar/async_client.py index 73899add5518..a966bdc57950 100644 --- a/packages/google-maps-solar/google/maps/solar_v1/services/solar/async_client.py +++ b/packages/google-maps-solar/google/maps/solar_v1/services/solar/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -53,6 +54,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, SolarTransport from .transports.grpc_asyncio import SolarGrpcAsyncIOTransport +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 SolarAsyncClient: """Service definition for the Solar API.""" @@ -246,6 +256,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.maps.solar_v1.SolarAsyncClient`.", + extra={ + "serviceName": "google.maps.solar.v1.Solar", + "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.maps.solar.v1.Solar", + "credentialsType": None, + }, + ) + async def find_closest_building_insights( self, request: Optional[ @@ -254,7 +286,7 @@ async def find_closest_building_insights( *, 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]]] = (), ) -> solar_service.BuildingInsights: r"""Locates the closest building to a query point. Returns an error with code ``NOT_FOUND`` if there are no buildings within @@ -292,8 +324,10 @@ async def sample_find_closest_building_insights(): 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.maps.solar_v1.types.BuildingInsights: @@ -334,7 +368,7 @@ async def get_data_layers( *, 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]]] = (), ) -> solar_service.DataLayers: r"""Gets solar information for a region surrounding a location. Returns an error with code ``NOT_FOUND`` if the location is @@ -372,8 +406,10 @@ async def sample_get_data_layers(): 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.maps.solar_v1.types.DataLayers: @@ -424,7 +460,7 @@ async def get_geo_tiff( *, 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]]] = (), ) -> httpbody_pb2.HttpBody: r"""Returns an image by its ID. @@ -460,8 +496,10 @@ async def sample_get_geo_tiff(): 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.api.httpbody_pb2.HttpBody: diff --git a/packages/google-maps-solar/google/maps/solar_v1/services/solar/client.py b/packages/google-maps-solar/google/maps/solar_v1/services/solar/client.py index 41740884fecb..48fcc5a94162 100644 --- a/packages/google-maps-solar/google/maps/solar_v1/services/solar/client.py +++ b/packages/google-maps-solar/google/maps/solar_v1/services/solar/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.api import httpbody_pb2 # type: ignore from google.protobuf import any_pb2 # type: ignore from google.type import date_pb2 # type: ignore @@ -558,6 +568,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( @@ -620,6 +634,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.maps.solar_v1.SolarClient`.", + extra={ + "serviceName": "google.maps.solar.v1.Solar", + "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.maps.solar.v1.Solar", + "credentialsType": None, + }, + ) + def find_closest_building_insights( self, request: Optional[ @@ -628,7 +665,7 @@ def find_closest_building_insights( *, 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]]] = (), ) -> solar_service.BuildingInsights: r"""Locates the closest building to a query point. Returns an error with code ``NOT_FOUND`` if there are no buildings within @@ -666,8 +703,10 @@ def sample_find_closest_building_insights(): 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.maps.solar_v1.types.BuildingInsights: @@ -708,7 +747,7 @@ def get_data_layers( *, 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]]] = (), ) -> solar_service.DataLayers: r"""Gets solar information for a region surrounding a location. Returns an error with code ``NOT_FOUND`` if the location is @@ -746,8 +785,10 @@ def sample_get_data_layers(): 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.maps.solar_v1.types.DataLayers: @@ -796,7 +837,7 @@ def get_geo_tiff( *, 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]]] = (), ) -> httpbody_pb2.HttpBody: r"""Returns an image by its ID. @@ -832,8 +873,10 @@ def sample_get_geo_tiff(): 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.api.httpbody_pb2.HttpBody: diff --git a/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/grpc.py b/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/grpc.py index 733317529da1..05659b774fc8 100644 --- a/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/grpc.py +++ b/packages/google-maps-solar/google/maps/solar_v1/services/solar/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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -21,12 +24,90 @@ 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.maps.solar_v1.types import solar_service from .base import DEFAULT_CLIENT_INFO, SolarTransport +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.maps.solar.v1.Solar", + "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.maps.solar.v1.Solar", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class SolarGrpcTransport(SolarTransport): """gRPC backend transport for Solar. @@ -180,7 +261,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 @@ -261,7 +347,7 @@ def find_closest_building_insights( if "find_closest_building_insights" not in self._stubs: self._stubs[ "find_closest_building_insights" - ] = self.grpc_channel.unary_unary( + ] = self._logged_channel.unary_unary( "/google.maps.solar.v1.Solar/FindClosestBuildingInsights", request_serializer=solar_service.FindClosestBuildingInsightsRequest.serialize, response_deserializer=solar_service.BuildingInsights.deserialize, @@ -289,7 +375,7 @@ def get_data_layers( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_data_layers" not in self._stubs: - self._stubs["get_data_layers"] = self.grpc_channel.unary_unary( + self._stubs["get_data_layers"] = self._logged_channel.unary_unary( "/google.maps.solar.v1.Solar/GetDataLayers", request_serializer=solar_service.GetDataLayersRequest.serialize, response_deserializer=solar_service.DataLayers.deserialize, @@ -315,7 +401,7 @@ def get_geo_tiff( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_geo_tiff" not in self._stubs: - self._stubs["get_geo_tiff"] = self.grpc_channel.unary_unary( + self._stubs["get_geo_tiff"] = self._logged_channel.unary_unary( "/google.maps.solar.v1.Solar/GetGeoTiff", request_serializer=solar_service.GetGeoTiffRequest.serialize, response_deserializer=httpbody_pb2.HttpBody.FromString, @@ -323,7 +409,7 @@ def get_geo_tiff( return self._stubs["get_geo_tiff"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/grpc_asyncio.py b/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/grpc_asyncio.py index 920b24e85628..3eab671a7e04 100644 --- a/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/grpc_asyncio.py +++ b/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -23,14 +26,93 @@ 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 from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.maps.solar_v1.types import solar_service from .base import DEFAULT_CLIENT_INFO, SolarTransport from .grpc import SolarGrpcTransport +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.maps.solar.v1.Solar", + "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.maps.solar.v1.Solar", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class SolarGrpcAsyncIOTransport(SolarTransport): """gRPC AsyncIO backend transport for Solar. @@ -227,10 +309,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 @@ -269,7 +354,7 @@ def find_closest_building_insights( if "find_closest_building_insights" not in self._stubs: self._stubs[ "find_closest_building_insights" - ] = self.grpc_channel.unary_unary( + ] = self._logged_channel.unary_unary( "/google.maps.solar.v1.Solar/FindClosestBuildingInsights", request_serializer=solar_service.FindClosestBuildingInsightsRequest.serialize, response_deserializer=solar_service.BuildingInsights.deserialize, @@ -299,7 +384,7 @@ def get_data_layers( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_data_layers" not in self._stubs: - self._stubs["get_data_layers"] = self.grpc_channel.unary_unary( + self._stubs["get_data_layers"] = self._logged_channel.unary_unary( "/google.maps.solar.v1.Solar/GetDataLayers", request_serializer=solar_service.GetDataLayersRequest.serialize, response_deserializer=solar_service.DataLayers.deserialize, @@ -325,7 +410,7 @@ def get_geo_tiff( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_geo_tiff" not in self._stubs: - self._stubs["get_geo_tiff"] = self.grpc_channel.unary_unary( + self._stubs["get_geo_tiff"] = self._logged_channel.unary_unary( "/google.maps.solar.v1.Solar/GetGeoTiff", request_serializer=solar_service.GetGeoTiffRequest.serialize, response_deserializer=httpbody_pb2.HttpBody.FromString, @@ -385,7 +470,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/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/rest.py b/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/rest.py index 27123714fe7d..876ab8b0ffcd 100644 --- a/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/rest.py +++ b/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -38,6 +38,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, @@ -94,9 +102,10 @@ def post_get_geo_tiff(self, response): def pre_find_closest_building_insights( self, request: solar_service.FindClosestBuildingInsightsRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - solar_service.FindClosestBuildingInsightsRequest, Sequence[Tuple[str, str]] + solar_service.FindClosestBuildingInsightsRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for find_closest_building_insights @@ -119,8 +128,10 @@ def post_find_closest_building_insights( def pre_get_data_layers( self, request: solar_service.GetDataLayersRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[solar_service.GetDataLayersRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + solar_service.GetDataLayersRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for get_data_layers Override in a subclass to manipulate the request or metadata @@ -142,8 +153,10 @@ def post_get_data_layers( def pre_get_geo_tiff( self, request: solar_service.GetGeoTiffRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[solar_service.GetGeoTiffRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + solar_service.GetGeoTiffRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for get_geo_tiff Override in a subclass to manipulate the request or metadata @@ -283,7 +296,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]]] = (), ) -> solar_service.BuildingInsights: r"""Call the find closest building insights method over HTTP. @@ -295,8 +308,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: ~.solar_service.BuildingInsights: @@ -310,6 +325,7 @@ def __call__( http_options = ( _BaseSolarRestTransport._BaseFindClosestBuildingInsights._get_http_options() ) + request, metadata = self._interceptor.pre_find_closest_building_insights( request, metadata ) @@ -322,6 +338,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.maps.solar_v1.SolarClient.FindClosestBuildingInsights", + extra={ + "serviceName": "google.maps.solar.v1.Solar", + "rpcName": "FindClosestBuildingInsights", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SolarRestTransport._FindClosestBuildingInsights._get_response( self._host, @@ -342,7 +385,29 @@ def __call__( pb_resp = solar_service.BuildingInsights.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_find_closest_building_insights(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = solar_service.BuildingInsights.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.maps.solar_v1.SolarClient.find_closest_building_insights", + extra={ + "serviceName": "google.maps.solar.v1.Solar", + "rpcName": "FindClosestBuildingInsights", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _GetDataLayers(_BaseSolarRestTransport._BaseGetDataLayers, SolarRestStub): @@ -377,7 +442,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]]] = (), ) -> solar_service.DataLayers: r"""Call the get data layers method over HTTP. @@ -387,8 +452,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: ~.solar_service.DataLayers: @@ -410,6 +477,7 @@ def __call__( http_options = ( _BaseSolarRestTransport._BaseGetDataLayers._get_http_options() ) + request, metadata = self._interceptor.pre_get_data_layers(request, metadata) transcoded_request = ( _BaseSolarRestTransport._BaseGetDataLayers._get_transcoded_request( @@ -424,6 +492,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.maps.solar_v1.SolarClient.GetDataLayers", + extra={ + "serviceName": "google.maps.solar.v1.Solar", + "rpcName": "GetDataLayers", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SolarRestTransport._GetDataLayers._get_response( self._host, @@ -444,7 +539,29 @@ def __call__( pb_resp = solar_service.DataLayers.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_data_layers(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = solar_service.DataLayers.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.maps.solar_v1.SolarClient.get_data_layers", + extra={ + "serviceName": "google.maps.solar.v1.Solar", + "rpcName": "GetDataLayers", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _GetGeoTiff(_BaseSolarRestTransport._BaseGetGeoTiff, SolarRestStub): @@ -479,7 +596,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]]] = (), ) -> httpbody_pb2.HttpBody: r"""Call the get geo tiff method over HTTP. @@ -489,8 +606,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: ~.httpbody_pb2.HttpBody: @@ -547,6 +666,7 @@ def __call__( """ http_options = _BaseSolarRestTransport._BaseGetGeoTiff._get_http_options() + request, metadata = self._interceptor.pre_get_geo_tiff(request, metadata) transcoded_request = ( _BaseSolarRestTransport._BaseGetGeoTiff._get_transcoded_request( @@ -561,6 +681,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.maps.solar_v1.SolarClient.GetGeoTiff", + extra={ + "serviceName": "google.maps.solar.v1.Solar", + "rpcName": "GetGeoTiff", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = SolarRestTransport._GetGeoTiff._get_response( self._host, @@ -581,7 +728,29 @@ def __call__( pb_resp = resp json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_geo_tiff(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.maps.solar_v1.SolarClient.get_geo_tiff", + extra={ + "serviceName": "google.maps.solar.v1.Solar", + "rpcName": "GetGeoTiff", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-maps-solar/samples/generated_samples/snippet_metadata_google.maps.solar.v1.json b/packages/google-maps-solar/samples/generated_samples/snippet_metadata_google.maps.solar.v1.json index 18729f320138..b0cd14fdb324 100644 --- a/packages/google-maps-solar/samples/generated_samples/snippet_metadata_google.maps.solar.v1.json +++ b/packages/google-maps-solar/samples/generated_samples/snippet_metadata_google.maps.solar.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-maps-solar", - "version": "0.1.4" + "version": "0.1.0" }, "snippets": [ { @@ -43,7 +43,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.solar_v1.types.BuildingInsights", @@ -119,7 +119,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.solar_v1.types.BuildingInsights", @@ -196,7 +196,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.solar_v1.types.DataLayers", @@ -272,7 +272,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.maps.solar_v1.types.DataLayers", @@ -349,7 +349,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.api.httpbody_pb2.HttpBody", @@ -425,7 +425,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.api.httpbody_pb2.HttpBody", diff --git a/packages/google-maps-solar/tests/unit/gapic/solar_v1/test_solar.py b/packages/google-maps-solar/tests/unit/gapic/solar_v1/test_solar.py index c7a25577650d..3771905a07a0 100644 --- a/packages/google-maps-solar/tests/unit/gapic/solar_v1/test_solar.py +++ b/packages/google-maps-solar/tests/unit/gapic/solar_v1/test_solar.py @@ -1693,6 +1693,7 @@ def test_find_closest_building_insights_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.find_closest_building_insights(request) @@ -1837,6 +1838,7 @@ def test_get_data_layers_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_data_layers(request) @@ -1982,6 +1984,7 @@ def test_get_geo_tiff_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_geo_tiff(request) @@ -2313,6 +2316,7 @@ def test_find_closest_building_insights_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.find_closest_building_insights(request) @@ -2353,6 +2357,7 @@ def test_find_closest_building_insights_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.find_closest_building_insights(request) # Establish that the response is the type that we expect. @@ -2396,6 +2401,7 @@ def test_find_closest_building_insights_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 = solar_service.BuildingInsights.to_json( solar_service.BuildingInsights() ) @@ -2442,6 +2448,7 @@ def test_get_data_layers_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.get_data_layers(request) @@ -2483,6 +2490,7 @@ def test_get_data_layers_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_data_layers(request) # Establish that the response is the type that we expect. @@ -2527,6 +2535,7 @@ def test_get_data_layers_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 = solar_service.DataLayers.to_json(solar_service.DataLayers()) req.return_value.content = return_value @@ -2569,6 +2578,7 @@ def test_get_geo_tiff_rest_bad_request(request_type=solar_service.GetGeoTiffRequ 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_geo_tiff(request) @@ -2602,6 +2612,7 @@ def test_get_geo_tiff_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_geo_tiff(request) # Establish that the response is the type that we expect. @@ -2641,6 +2652,7 @@ def test_get_geo_tiff_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 = json_format.MessageToJson(httpbody_pb2.HttpBody()) req.return_value.content = return_value diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts/gapic_version.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts/gapic_version.py index d1a1a883babd..558c8aab67c5 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts/gapic_version.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.2.2" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/gapic_version.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/gapic_version.py index d1a1a883babd..558c8aab67c5 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/gapic_version.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.2.2" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/async_client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/async_client.py index 1cbc438a3fa5..0c4f7b7c70c1 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/async_client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -51,6 +52,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, AccountIssueServiceTransport from .transports.grpc_asyncio import AccountIssueServiceGrpcAsyncIOTransport +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 AccountIssueServiceAsyncClient: """Service to support ``AccountIssueService`` API.""" @@ -264,6 +274,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.shopping.merchant.accounts_v1beta.AccountIssueServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountIssueService", + "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.shopping.merchant.accounts.v1beta.AccountIssueService", + "credentialsType": None, + }, + ) + async def list_account_issues( self, request: Optional[Union[accountissue.ListAccountIssuesRequest, dict]] = None, @@ -271,7 +303,7 @@ async def list_account_issues( 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.ListAccountIssuesAsyncPager: r"""Lists all account issues of a Merchant Center account. @@ -316,8 +348,10 @@ async def sample_list_account_issues(): 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.shopping.merchant_accounts_v1beta.services.account_issue_service.pagers.ListAccountIssuesAsyncPager: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/client.py index f519f463d0c9..7b2617438d45 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.shopping.merchant_accounts_v1beta.services.account_issue_service import ( pagers, ) @@ -594,6 +604,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( @@ -660,6 +674,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.shopping.merchant.accounts_v1beta.AccountIssueServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountIssueService", + "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.shopping.merchant.accounts.v1beta.AccountIssueService", + "credentialsType": None, + }, + ) + def list_account_issues( self, request: Optional[Union[accountissue.ListAccountIssuesRequest, dict]] = None, @@ -667,7 +704,7 @@ def list_account_issues( 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.ListAccountIssuesPager: r"""Lists all account issues of a Merchant Center account. @@ -712,8 +749,10 @@ def sample_list_account_issues(): 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.shopping.merchant_accounts_v1beta.services.account_issue_service.pagers.ListAccountIssuesPager: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/pagers.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/pagers.py index 0aef6d8bc843..2c02d846a735 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/pagers.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/pagers.py @@ -67,7 +67,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. @@ -81,8 +81,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 = accountissue.ListAccountIssuesRequest(request) @@ -141,7 +143,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. @@ -155,8 +157,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 = accountissue.ListAccountIssuesRequest(request) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/grpc.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/grpc.py index 497d5655bac6..141540f0e5ab 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/grpc.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -20,12 +23,90 @@ 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.shopping.merchant_accounts_v1beta.types import accountissue from .base import DEFAULT_CLIENT_INFO, AccountIssueServiceTransport +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.shopping.merchant.accounts.v1beta.AccountIssueService", + "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.shopping.merchant.accounts.v1beta.AccountIssueService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class AccountIssueServiceGrpcTransport(AccountIssueServiceTransport): """gRPC backend transport for AccountIssueService. @@ -179,7 +260,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 @@ -256,7 +342,7 @@ def list_account_issues( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_account_issues" not in self._stubs: - self._stubs["list_account_issues"] = self.grpc_channel.unary_unary( + self._stubs["list_account_issues"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AccountIssueService/ListAccountIssues", request_serializer=accountissue.ListAccountIssuesRequest.serialize, response_deserializer=accountissue.ListAccountIssuesResponse.deserialize, @@ -264,7 +350,7 @@ def list_account_issues( return self._stubs["list_account_issues"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/grpc_asyncio.py index 240f7523f536..ec1db1b4df83 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -22,14 +25,93 @@ 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 from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_accounts_v1beta.types import accountissue from .base import DEFAULT_CLIENT_INFO, AccountIssueServiceTransport from .grpc import AccountIssueServiceGrpcTransport +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.shopping.merchant.accounts.v1beta.AccountIssueService", + "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.shopping.merchant.accounts.v1beta.AccountIssueService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class AccountIssueServiceGrpcAsyncIOTransport(AccountIssueServiceTransport): """gRPC AsyncIO backend transport for AccountIssueService. @@ -226,10 +308,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 @@ -265,7 +350,7 @@ def list_account_issues( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_account_issues" not in self._stubs: - self._stubs["list_account_issues"] = self.grpc_channel.unary_unary( + self._stubs["list_account_issues"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AccountIssueService/ListAccountIssues", request_serializer=accountissue.ListAccountIssuesRequest.serialize, response_deserializer=accountissue.ListAccountIssuesResponse.deserialize, @@ -288,7 +373,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/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/rest.py index 00df2d37ee7c..f50f616ca4c4 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -37,6 +37,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, @@ -77,8 +85,10 @@ def post_list_account_issues(self, response): def pre_list_account_issues( self, request: accountissue.ListAccountIssuesRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[accountissue.ListAccountIssuesRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + accountissue.ListAccountIssuesRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for list_account_issues Override in a subclass to manipulate the request or metadata @@ -219,7 +229,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]]] = (), ) -> accountissue.ListAccountIssuesResponse: r"""Call the list account issues method over HTTP. @@ -229,8 +239,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: ~.accountissue.ListAccountIssuesResponse: @@ -240,6 +252,7 @@ def __call__( http_options = ( _BaseAccountIssueServiceRestTransport._BaseListAccountIssues._get_http_options() ) + request, metadata = self._interceptor.pre_list_account_issues( request, metadata ) @@ -252,6 +265,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.shopping.merchant.accounts_v1beta.AccountIssueServiceClient.ListAccountIssues", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountIssueService", + "rpcName": "ListAccountIssues", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ( AccountIssueServiceRestTransport._ListAccountIssues._get_response( @@ -274,7 +314,31 @@ def __call__( pb_resp = accountissue.ListAccountIssuesResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_account_issues(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = accountissue.ListAccountIssuesResponse.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.shopping.merchant.accounts_v1beta.AccountIssueServiceClient.list_account_issues", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountIssueService", + "rpcName": "ListAccountIssues", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/async_client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/async_client.py index 136885e029cb..ee92fa2ce59c 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/async_client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -55,6 +56,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, AccountTaxServiceTransport from .transports.grpc_asyncio import AccountTaxServiceGrpcAsyncIOTransport +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 AccountTaxServiceAsyncClient: """Manages account level tax setting data. @@ -271,6 +281,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.shopping.merchant.accounts_v1beta.AccountTaxServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountTaxService", + "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.shopping.merchant.accounts.v1beta.AccountTaxService", + "credentialsType": None, + }, + ) + async def get_account_tax( self, request: Optional[Union[account_tax.GetAccountTaxRequest, dict]] = None, @@ -278,7 +310,7 @@ async def get_account_tax( 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]]] = (), ) -> account_tax.AccountTax: r"""Returns the tax rules that match the conditions of GetAccountTaxRequest @@ -322,8 +354,10 @@ async def sample_get_account_tax(): 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.shopping.merchant_accounts_v1beta.types.AccountTax: @@ -385,7 +419,7 @@ async def list_account_tax( 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.ListAccountTaxAsyncPager: r"""Lists the tax settings of the sub-accounts only in your Merchant Center account. @@ -437,8 +471,10 @@ async def sample_list_account_tax(): 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.shopping.merchant_accounts_v1beta.services.account_tax_service.pagers.ListAccountTaxAsyncPager: @@ -517,7 +553,7 @@ async def update_account_tax( 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]]] = (), ) -> gsma_account_tax.AccountTax: r"""Updates the tax settings of the account. @@ -564,8 +600,10 @@ async def sample_update_account_tax(): 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.shopping.merchant_accounts_v1beta.types.AccountTax: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/client.py index 40389337002c..e861d5641259 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.protobuf import field_mask_pb2 # type: ignore from google.shopping.merchant_accounts_v1beta.services.account_tax_service import pagers @@ -588,6 +598,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( @@ -654,6 +668,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.shopping.merchant.accounts_v1beta.AccountTaxServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountTaxService", + "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.shopping.merchant.accounts.v1beta.AccountTaxService", + "credentialsType": None, + }, + ) + def get_account_tax( self, request: Optional[Union[account_tax.GetAccountTaxRequest, dict]] = None, @@ -661,7 +698,7 @@ def get_account_tax( 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]]] = (), ) -> account_tax.AccountTax: r"""Returns the tax rules that match the conditions of GetAccountTaxRequest @@ -705,8 +742,10 @@ def sample_get_account_tax(): 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.shopping.merchant_accounts_v1beta.types.AccountTax: @@ -765,7 +804,7 @@ def list_account_tax( 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.ListAccountTaxPager: r"""Lists the tax settings of the sub-accounts only in your Merchant Center account. @@ -817,8 +856,10 @@ def sample_list_account_tax(): 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.shopping.merchant_accounts_v1beta.services.account_tax_service.pagers.ListAccountTaxPager: @@ -894,7 +935,7 @@ def update_account_tax( 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]]] = (), ) -> gsma_account_tax.AccountTax: r"""Updates the tax settings of the account. @@ -941,8 +982,10 @@ def sample_update_account_tax(): 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.shopping.merchant_accounts_v1beta.types.AccountTax: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/pagers.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/pagers.py index 21dd67c0076f..8ca74417eaf8 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/pagers.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/pagers.py @@ -67,7 +67,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. @@ -81,8 +81,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 = account_tax.ListAccountTaxRequest(request) @@ -141,7 +143,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. @@ -155,8 +157,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 = account_tax.ListAccountTaxRequest(request) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/grpc.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/grpc.py index 4eb4c19924fc..4c975ab748d2 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/grpc.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -20,7 +23,10 @@ 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.shopping.merchant_accounts_v1beta.types import ( account_tax as gsma_account_tax, @@ -29,6 +35,81 @@ from .base import DEFAULT_CLIENT_INFO, AccountTaxServiceTransport +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.shopping.merchant.accounts.v1beta.AccountTaxService", + "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.shopping.merchant.accounts.v1beta.AccountTaxService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class AccountTaxServiceGrpcTransport(AccountTaxServiceTransport): """gRPC backend transport for AccountTaxService. @@ -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 @@ -261,7 +347,7 @@ def get_account_tax( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_account_tax" not in self._stubs: - self._stubs["get_account_tax"] = self.grpc_channel.unary_unary( + self._stubs["get_account_tax"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AccountTaxService/GetAccountTax", request_serializer=account_tax.GetAccountTaxRequest.serialize, response_deserializer=account_tax.AccountTax.deserialize, @@ -292,7 +378,7 @@ def list_account_tax( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_account_tax" not in self._stubs: - self._stubs["list_account_tax"] = self.grpc_channel.unary_unary( + self._stubs["list_account_tax"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AccountTaxService/ListAccountTax", request_serializer=account_tax.ListAccountTaxRequest.serialize, response_deserializer=account_tax.ListAccountTaxResponse.deserialize, @@ -320,7 +406,7 @@ def update_account_tax( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_account_tax" not in self._stubs: - self._stubs["update_account_tax"] = self.grpc_channel.unary_unary( + self._stubs["update_account_tax"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AccountTaxService/UpdateAccountTax", request_serializer=gsma_account_tax.UpdateAccountTaxRequest.serialize, response_deserializer=gsma_account_tax.AccountTax.deserialize, @@ -328,7 +414,7 @@ def update_account_tax( return self._stubs["update_account_tax"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/grpc_asyncio.py index 620cf2c12ae6..68080d549d5b 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -22,8 +25,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 from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_accounts_v1beta.types import ( account_tax as gsma_account_tax, @@ -33,6 +39,82 @@ from .base import DEFAULT_CLIENT_INFO, AccountTaxServiceTransport from .grpc import AccountTaxServiceGrpcTransport +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.shopping.merchant.accounts.v1beta.AccountTaxService", + "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.shopping.merchant.accounts.v1beta.AccountTaxService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class AccountTaxServiceGrpcAsyncIOTransport(AccountTaxServiceTransport): """gRPC AsyncIO backend transport for AccountTaxService. @@ -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 @@ -271,7 +356,7 @@ def get_account_tax( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_account_tax" not in self._stubs: - self._stubs["get_account_tax"] = self.grpc_channel.unary_unary( + self._stubs["get_account_tax"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AccountTaxService/GetAccountTax", request_serializer=account_tax.GetAccountTaxRequest.serialize, response_deserializer=account_tax.AccountTax.deserialize, @@ -303,7 +388,7 @@ def list_account_tax( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_account_tax" not in self._stubs: - self._stubs["list_account_tax"] = self.grpc_channel.unary_unary( + self._stubs["list_account_tax"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AccountTaxService/ListAccountTax", request_serializer=account_tax.ListAccountTaxRequest.serialize, response_deserializer=account_tax.ListAccountTaxResponse.deserialize, @@ -332,7 +417,7 @@ def update_account_tax( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_account_tax" not in self._stubs: - self._stubs["update_account_tax"] = self.grpc_channel.unary_unary( + self._stubs["update_account_tax"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AccountTaxService/UpdateAccountTax", request_serializer=gsma_account_tax.UpdateAccountTaxRequest.serialize, response_deserializer=gsma_account_tax.AccountTax.deserialize, @@ -365,7 +450,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/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/rest.py index abf839241aca..4c562090d9b4 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -40,6 +40,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, @@ -96,8 +104,10 @@ def post_update_account_tax(self, response): def pre_get_account_tax( self, request: account_tax.GetAccountTaxRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[account_tax.GetAccountTaxRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + account_tax.GetAccountTaxRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for get_account_tax Override in a subclass to manipulate the request or metadata @@ -119,8 +129,10 @@ def post_get_account_tax( def pre_list_account_tax( self, request: account_tax.ListAccountTaxRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[account_tax.ListAccountTaxRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + account_tax.ListAccountTaxRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for list_account_tax Override in a subclass to manipulate the request or metadata @@ -142,8 +154,11 @@ def post_list_account_tax( def pre_update_account_tax( self, request: gsma_account_tax.UpdateAccountTaxRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[gsma_account_tax.UpdateAccountTaxRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gsma_account_tax.UpdateAccountTaxRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: """Pre-rpc interceptor for update_account_tax Override in a subclass to manipulate the request or metadata @@ -288,7 +303,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]]] = (), ) -> account_tax.AccountTax: r"""Call the get account tax method over HTTP. @@ -298,8 +313,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: ~.account_tax.AccountTax: @@ -312,6 +329,7 @@ def __call__( http_options = ( _BaseAccountTaxServiceRestTransport._BaseGetAccountTax._get_http_options() ) + request, metadata = self._interceptor.pre_get_account_tax(request, metadata) transcoded_request = _BaseAccountTaxServiceRestTransport._BaseGetAccountTax._get_transcoded_request( http_options, request @@ -322,6 +340,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.shopping.merchant.accounts_v1beta.AccountTaxServiceClient.GetAccountTax", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountTaxService", + "rpcName": "GetAccountTax", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = AccountTaxServiceRestTransport._GetAccountTax._get_response( self._host, @@ -342,7 +387,29 @@ def __call__( pb_resp = account_tax.AccountTax.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_account_tax(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = account_tax.AccountTax.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.shopping.merchant.accounts_v1beta.AccountTaxServiceClient.get_account_tax", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountTaxService", + "rpcName": "GetAccountTax", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListAccountTax( @@ -380,7 +447,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]]] = (), ) -> account_tax.ListAccountTaxResponse: r"""Call the list account tax method over HTTP. @@ -394,8 +461,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: ~.account_tax.ListAccountTaxResponse: @@ -409,6 +478,7 @@ def __call__( http_options = ( _BaseAccountTaxServiceRestTransport._BaseListAccountTax._get_http_options() ) + request, metadata = self._interceptor.pre_list_account_tax( request, metadata ) @@ -421,6 +491,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.shopping.merchant.accounts_v1beta.AccountTaxServiceClient.ListAccountTax", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountTaxService", + "rpcName": "ListAccountTax", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = AccountTaxServiceRestTransport._ListAccountTax._get_response( self._host, @@ -441,7 +538,31 @@ def __call__( pb_resp = account_tax.ListAccountTaxResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_account_tax(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = account_tax.ListAccountTaxResponse.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.shopping.merchant.accounts_v1beta.AccountTaxServiceClient.list_account_tax", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountTaxService", + "rpcName": "ListAccountTax", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _UpdateAccountTax( @@ -480,7 +601,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]]] = (), ) -> gsma_account_tax.AccountTax: r"""Call the update account tax method over HTTP. @@ -490,8 +611,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: ~.gsma_account_tax.AccountTax: @@ -504,6 +627,7 @@ def __call__( http_options = ( _BaseAccountTaxServiceRestTransport._BaseUpdateAccountTax._get_http_options() ) + request, metadata = self._interceptor.pre_update_account_tax( request, metadata ) @@ -520,6 +644,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.shopping.merchant.accounts_v1beta.AccountTaxServiceClient.UpdateAccountTax", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountTaxService", + "rpcName": "UpdateAccountTax", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = AccountTaxServiceRestTransport._UpdateAccountTax._get_response( self._host, @@ -541,7 +692,29 @@ def __call__( pb_resp = gsma_account_tax.AccountTax.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_account_tax(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = gsma_account_tax.AccountTax.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.shopping.merchant.accounts_v1beta.AccountTaxServiceClient.update_account_tax", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountTaxService", + "rpcName": "UpdateAccountTax", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/async_client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/async_client.py index 7a39ba6829d3..9149f44506dc 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/async_client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -52,6 +53,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, AccountsServiceTransport from .transports.grpc_asyncio import AccountsServiceGrpcAsyncIOTransport +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 AccountsServiceAsyncClient: """Service to support Accounts API.""" @@ -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.shopping.merchant.accounts_v1beta.AccountsServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountsService", + "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.shopping.merchant.accounts.v1beta.AccountsService", + "credentialsType": None, + }, + ) + async def get_account( self, request: Optional[Union[accounts.GetAccountRequest, dict]] = None, @@ -272,7 +304,7 @@ async def get_account( 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]]] = (), ) -> accounts.Account: r"""Retrieves an account from your Merchant Center account. After inserting, updating, or deleting an @@ -318,8 +350,10 @@ async def sample_get_account(): 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.shopping.merchant_accounts_v1beta.types.Account: @@ -379,7 +413,7 @@ async def create_and_configure_account( *, 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]]] = (), ) -> accounts.Account: r"""Creates a standalone Merchant Center account with additional configuration. Adds the user that makes the @@ -422,8 +456,10 @@ async def sample_create_and_configure_account(): 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.shopping.merchant_accounts_v1beta.types.Account: @@ -462,7 +498,7 @@ async def delete_account( 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 the specified account regardless of its type: standalone, MCA or sub-account. Deleting an MCA leads to the @@ -508,8 +544,10 @@ async def sample_delete_account(): 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 @@ -562,7 +600,7 @@ async def update_account( 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]]] = (), ) -> accounts.Account: r"""Updates an account regardless of its type: standalone, MCA or sub-account. Executing this method @@ -618,8 +656,10 @@ async def sample_update_account(): 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.shopping.merchant_accounts_v1beta.types.Account: @@ -681,7 +721,7 @@ async def list_accounts( *, 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.ListAccountsAsyncPager: r"""Lists accounts accessible to the calling user and matching the constraints of the request such as page @@ -724,8 +764,10 @@ async def sample_list_accounts(): 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.shopping.merchant_accounts_v1beta.services.accounts_service.pagers.ListAccountsAsyncPager: @@ -779,7 +821,7 @@ async def list_sub_accounts( provider: 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.ListSubAccountsAsyncPager: r"""List all sub-accounts for a given multi client account. This is a convenience wrapper for the more powerful ``ListAccounts`` @@ -827,8 +869,10 @@ async def sample_list_sub_accounts(): 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.shopping.merchant_accounts_v1beta.services.accounts_service.pagers.ListSubAccountsAsyncPager: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/client.py index 574d711de7c2..b494944f8580 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.protobuf import field_mask_pb2 # type: ignore from google.type import datetime_pb2 # type: ignore @@ -608,6 +618,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( @@ -673,6 +687,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.shopping.merchant.accounts_v1beta.AccountsServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountsService", + "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.shopping.merchant.accounts.v1beta.AccountsService", + "credentialsType": None, + }, + ) + def get_account( self, request: Optional[Union[accounts.GetAccountRequest, dict]] = None, @@ -680,7 +717,7 @@ def get_account( 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]]] = (), ) -> accounts.Account: r"""Retrieves an account from your Merchant Center account. After inserting, updating, or deleting an @@ -726,8 +763,10 @@ def sample_get_account(): 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.shopping.merchant_accounts_v1beta.types.Account: @@ -784,7 +823,7 @@ def create_and_configure_account( *, 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]]] = (), ) -> accounts.Account: r"""Creates a standalone Merchant Center account with additional configuration. Adds the user that makes the @@ -827,8 +866,10 @@ def sample_create_and_configure_account(): 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.shopping.merchant_accounts_v1beta.types.Account: @@ -867,7 +908,7 @@ def delete_account( 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 the specified account regardless of its type: standalone, MCA or sub-account. Deleting an MCA leads to the @@ -913,8 +954,10 @@ def sample_delete_account(): 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 @@ -964,7 +1007,7 @@ def update_account( 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]]] = (), ) -> accounts.Account: r"""Updates an account regardless of its type: standalone, MCA or sub-account. Executing this method @@ -1020,8 +1063,10 @@ def sample_update_account(): 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.shopping.merchant_accounts_v1beta.types.Account: @@ -1080,7 +1125,7 @@ def list_accounts( *, 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.ListAccountsPager: r"""Lists accounts accessible to the calling user and matching the constraints of the request such as page @@ -1123,8 +1168,10 @@ def sample_list_accounts(): 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.shopping.merchant_accounts_v1beta.services.accounts_service.pagers.ListAccountsPager: @@ -1176,7 +1223,7 @@ def list_sub_accounts( provider: 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.ListSubAccountsPager: r"""List all sub-accounts for a given multi client account. This is a convenience wrapper for the more powerful ``ListAccounts`` @@ -1224,8 +1271,10 @@ def sample_list_sub_accounts(): 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.shopping.merchant_accounts_v1beta.services.accounts_service.pagers.ListSubAccountsPager: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/pagers.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/pagers.py index 9c4d852d9a9b..de4f59a8bc09 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/pagers.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/pagers.py @@ -67,7 +67,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. @@ -81,8 +81,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 = accounts.ListAccountsRequest(request) @@ -141,7 +143,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. @@ -155,8 +157,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 = accounts.ListAccountsRequest(request) @@ -219,7 +223,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. @@ -233,8 +237,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 = accounts.ListSubAccountsRequest(request) @@ -293,7 +299,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. @@ -307,8 +313,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 = accounts.ListSubAccountsRequest(request) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/grpc.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/grpc.py index c2c0d8c4abc7..f32791d4bfdb 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/grpc.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -21,12 +24,90 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore +import proto # type: ignore from google.shopping.merchant_accounts_v1beta.types import accounts from .base import DEFAULT_CLIENT_INFO, AccountsServiceTransport +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.shopping.merchant.accounts.v1beta.AccountsService", + "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.shopping.merchant.accounts.v1beta.AccountsService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class AccountsServiceGrpcTransport(AccountsServiceTransport): """gRPC backend transport for AccountsService. @@ -180,7 +261,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 @@ -255,7 +341,7 @@ def get_account(self) -> Callable[[accounts.GetAccountRequest], accounts.Account # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_account" not in self._stubs: - self._stubs["get_account"] = self.grpc_channel.unary_unary( + self._stubs["get_account"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AccountsService/GetAccount", request_serializer=accounts.GetAccountRequest.serialize, response_deserializer=accounts.Account.deserialize, @@ -283,7 +369,9 @@ def create_and_configure_account( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_and_configure_account" not in self._stubs: - self._stubs["create_and_configure_account"] = self.grpc_channel.unary_unary( + self._stubs[ + "create_and_configure_account" + ] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AccountsService/CreateAndConfigureAccount", request_serializer=accounts.CreateAndConfigureAccountRequest.serialize, response_deserializer=accounts.Account.deserialize, @@ -315,7 +403,7 @@ def delete_account( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_account" not in self._stubs: - self._stubs["delete_account"] = self.grpc_channel.unary_unary( + self._stubs["delete_account"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AccountsService/DeleteAccount", request_serializer=accounts.DeleteAccountRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -343,7 +431,7 @@ def update_account( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_account" not in self._stubs: - self._stubs["update_account"] = self.grpc_channel.unary_unary( + self._stubs["update_account"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AccountsService/UpdateAccount", request_serializer=accounts.UpdateAccountRequest.serialize, response_deserializer=accounts.Account.deserialize, @@ -376,7 +464,7 @@ def list_accounts( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_accounts" not in self._stubs: - self._stubs["list_accounts"] = self.grpc_channel.unary_unary( + self._stubs["list_accounts"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AccountsService/ListAccounts", request_serializer=accounts.ListAccountsRequest.serialize, response_deserializer=accounts.ListAccountsResponse.deserialize, @@ -406,7 +494,7 @@ def list_sub_accounts( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_sub_accounts" not in self._stubs: - self._stubs["list_sub_accounts"] = self.grpc_channel.unary_unary( + self._stubs["list_sub_accounts"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AccountsService/ListSubAccounts", request_serializer=accounts.ListSubAccountsRequest.serialize, response_deserializer=accounts.ListSubAccountsResponse.deserialize, @@ -414,7 +502,7 @@ def list_sub_accounts( return self._stubs["list_sub_accounts"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/grpc_asyncio.py index 1e3d872aa0b2..18e8ed5ca3cd 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -23,14 +26,93 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_accounts_v1beta.types import accounts from .base import DEFAULT_CLIENT_INFO, AccountsServiceTransport from .grpc import AccountsServiceGrpcTransport +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.shopping.merchant.accounts.v1beta.AccountsService", + "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.shopping.merchant.accounts.v1beta.AccountsService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class AccountsServiceGrpcAsyncIOTransport(AccountsServiceTransport): """gRPC AsyncIO backend transport for AccountsService. @@ -227,10 +309,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 @@ -265,7 +350,7 @@ def get_account( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_account" not in self._stubs: - self._stubs["get_account"] = self.grpc_channel.unary_unary( + self._stubs["get_account"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AccountsService/GetAccount", request_serializer=accounts.GetAccountRequest.serialize, response_deserializer=accounts.Account.deserialize, @@ -295,7 +380,9 @@ def create_and_configure_account( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_and_configure_account" not in self._stubs: - self._stubs["create_and_configure_account"] = self.grpc_channel.unary_unary( + self._stubs[ + "create_and_configure_account" + ] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AccountsService/CreateAndConfigureAccount", request_serializer=accounts.CreateAndConfigureAccountRequest.serialize, response_deserializer=accounts.Account.deserialize, @@ -327,7 +414,7 @@ def delete_account( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_account" not in self._stubs: - self._stubs["delete_account"] = self.grpc_channel.unary_unary( + self._stubs["delete_account"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AccountsService/DeleteAccount", request_serializer=accounts.DeleteAccountRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -355,7 +442,7 @@ def update_account( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_account" not in self._stubs: - self._stubs["update_account"] = self.grpc_channel.unary_unary( + self._stubs["update_account"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AccountsService/UpdateAccount", request_serializer=accounts.UpdateAccountRequest.serialize, response_deserializer=accounts.Account.deserialize, @@ -390,7 +477,7 @@ def list_accounts( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_accounts" not in self._stubs: - self._stubs["list_accounts"] = self.grpc_channel.unary_unary( + self._stubs["list_accounts"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AccountsService/ListAccounts", request_serializer=accounts.ListAccountsRequest.serialize, response_deserializer=accounts.ListAccountsResponse.deserialize, @@ -422,7 +509,7 @@ def list_sub_accounts( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_sub_accounts" not in self._stubs: - self._stubs["list_sub_accounts"] = self.grpc_channel.unary_unary( + self._stubs["list_sub_accounts"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AccountsService/ListSubAccounts", request_serializer=accounts.ListSubAccountsRequest.serialize, response_deserializer=accounts.ListSubAccountsResponse.deserialize, @@ -470,7 +557,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/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/rest.py index e497a179734f..ccc7fb9ca712 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -38,6 +38,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, @@ -114,8 +122,11 @@ def post_update_account(self, response): def pre_create_and_configure_account( self, request: accounts.CreateAndConfigureAccountRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[accounts.CreateAndConfigureAccountRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + accounts.CreateAndConfigureAccountRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: """Pre-rpc interceptor for create_and_configure_account Override in a subclass to manipulate the request or metadata @@ -137,8 +148,8 @@ def post_create_and_configure_account( def pre_delete_account( self, request: accounts.DeleteAccountRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[accounts.DeleteAccountRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[accounts.DeleteAccountRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for delete_account Override in a subclass to manipulate the request or metadata @@ -147,8 +158,10 @@ def pre_delete_account( return request, metadata def pre_get_account( - self, request: accounts.GetAccountRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[accounts.GetAccountRequest, Sequence[Tuple[str, str]]]: + self, + request: accounts.GetAccountRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[accounts.GetAccountRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for get_account Override in a subclass to manipulate the request or metadata @@ -166,8 +179,10 @@ def post_get_account(self, response: accounts.Account) -> accounts.Account: return response def pre_list_accounts( - self, request: accounts.ListAccountsRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[accounts.ListAccountsRequest, Sequence[Tuple[str, str]]]: + self, + request: accounts.ListAccountsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[accounts.ListAccountsRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for list_accounts Override in a subclass to manipulate the request or metadata @@ -189,8 +204,10 @@ def post_list_accounts( def pre_list_sub_accounts( self, request: accounts.ListSubAccountsRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[accounts.ListSubAccountsRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + accounts.ListSubAccountsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for list_sub_accounts Override in a subclass to manipulate the request or metadata @@ -212,8 +229,8 @@ def post_list_sub_accounts( def pre_update_account( self, request: accounts.UpdateAccountRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[accounts.UpdateAccountRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[accounts.UpdateAccountRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for update_account Override in a subclass to manipulate the request or metadata @@ -353,7 +370,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]]] = (), ) -> accounts.Account: r"""Call the create and configure account method over HTTP. @@ -365,8 +382,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: ~.accounts.Account: @@ -376,6 +395,7 @@ def __call__( http_options = ( _BaseAccountsServiceRestTransport._BaseCreateAndConfigureAccount._get_http_options() ) + request, metadata = self._interceptor.pre_create_and_configure_account( request, metadata ) @@ -392,6 +412,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.shopping.merchant.accounts_v1beta.AccountsServiceClient.CreateAndConfigureAccount", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountsService", + "rpcName": "CreateAndConfigureAccount", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ( AccountsServiceRestTransport._CreateAndConfigureAccount._get_response( @@ -415,7 +462,29 @@ def __call__( pb_resp = accounts.Account.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_and_configure_account(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = accounts.Account.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.shopping.merchant.accounts_v1beta.AccountsServiceClient.create_and_configure_account", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountsService", + "rpcName": "CreateAndConfigureAccount", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _DeleteAccount( @@ -452,7 +521,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 account method over HTTP. @@ -462,13 +531,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 = ( _BaseAccountsServiceRestTransport._BaseDeleteAccount._get_http_options() ) + request, metadata = self._interceptor.pre_delete_account(request, metadata) transcoded_request = _BaseAccountsServiceRestTransport._BaseDeleteAccount._get_transcoded_request( http_options, request @@ -479,6 +551,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.shopping.merchant.accounts_v1beta.AccountsServiceClient.DeleteAccount", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountsService", + "rpcName": "DeleteAccount", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = AccountsServiceRestTransport._DeleteAccount._get_response( self._host, @@ -528,7 +627,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]]] = (), ) -> accounts.Account: r"""Call the get account method over HTTP. @@ -538,8 +637,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: ~.accounts.Account: @@ -549,6 +650,7 @@ def __call__( http_options = ( _BaseAccountsServiceRestTransport._BaseGetAccount._get_http_options() ) + request, metadata = self._interceptor.pre_get_account(request, metadata) transcoded_request = _BaseAccountsServiceRestTransport._BaseGetAccount._get_transcoded_request( http_options, request @@ -559,6 +661,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.shopping.merchant.accounts_v1beta.AccountsServiceClient.GetAccount", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountsService", + "rpcName": "GetAccount", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = AccountsServiceRestTransport._GetAccount._get_response( self._host, @@ -579,7 +708,29 @@ def __call__( pb_resp = accounts.Account.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_account(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = accounts.Account.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.shopping.merchant.accounts_v1beta.AccountsServiceClient.get_account", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountsService", + "rpcName": "GetAccount", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListAccounts( @@ -616,7 +767,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]]] = (), ) -> accounts.ListAccountsResponse: r"""Call the list accounts method over HTTP. @@ -626,8 +777,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: ~.accounts.ListAccountsResponse: @@ -637,6 +790,7 @@ def __call__( http_options = ( _BaseAccountsServiceRestTransport._BaseListAccounts._get_http_options() ) + request, metadata = self._interceptor.pre_list_accounts(request, metadata) transcoded_request = _BaseAccountsServiceRestTransport._BaseListAccounts._get_transcoded_request( http_options, request @@ -647,6 +801,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.shopping.merchant.accounts_v1beta.AccountsServiceClient.ListAccounts", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountsService", + "rpcName": "ListAccounts", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = AccountsServiceRestTransport._ListAccounts._get_response( self._host, @@ -667,7 +848,29 @@ def __call__( pb_resp = accounts.ListAccountsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_accounts(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = accounts.ListAccountsResponse.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.shopping.merchant.accounts_v1beta.AccountsServiceClient.list_accounts", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountsService", + "rpcName": "ListAccounts", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListSubAccounts( @@ -704,7 +907,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]]] = (), ) -> accounts.ListSubAccountsResponse: r"""Call the list sub accounts method over HTTP. @@ -714,8 +917,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: ~.accounts.ListSubAccountsResponse: @@ -725,6 +930,7 @@ def __call__( http_options = ( _BaseAccountsServiceRestTransport._BaseListSubAccounts._get_http_options() ) + request, metadata = self._interceptor.pre_list_sub_accounts( request, metadata ) @@ -737,6 +943,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.shopping.merchant.accounts_v1beta.AccountsServiceClient.ListSubAccounts", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountsService", + "rpcName": "ListSubAccounts", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = AccountsServiceRestTransport._ListSubAccounts._get_response( self._host, @@ -757,7 +990,31 @@ def __call__( pb_resp = accounts.ListSubAccountsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_sub_accounts(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = accounts.ListSubAccountsResponse.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.shopping.merchant.accounts_v1beta.AccountsServiceClient.list_sub_accounts", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountsService", + "rpcName": "ListSubAccounts", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _UpdateAccount( @@ -795,7 +1052,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]]] = (), ) -> accounts.Account: r"""Call the update account method over HTTP. @@ -805,8 +1062,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: ~.accounts.Account: @@ -816,6 +1075,7 @@ def __call__( http_options = ( _BaseAccountsServiceRestTransport._BaseUpdateAccount._get_http_options() ) + request, metadata = self._interceptor.pre_update_account(request, metadata) transcoded_request = _BaseAccountsServiceRestTransport._BaseUpdateAccount._get_transcoded_request( http_options, request @@ -830,6 +1090,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.shopping.merchant.accounts_v1beta.AccountsServiceClient.UpdateAccount", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountsService", + "rpcName": "UpdateAccount", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = AccountsServiceRestTransport._UpdateAccount._get_response( self._host, @@ -851,7 +1138,29 @@ def __call__( pb_resp = accounts.Account.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_account(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = accounts.Account.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.shopping.merchant.accounts_v1beta.AccountsServiceClient.update_account", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AccountsService", + "rpcName": "UpdateAccount", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/async_client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/async_client.py index e01855825f41..53f565e5f2f8 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/async_client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -50,6 +51,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, AutofeedSettingsServiceTransport from .transports.grpc_asyncio import AutofeedSettingsServiceGrpcAsyncIOTransport +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 AutofeedSettingsServiceAsyncClient: """Service to support @@ -272,6 +282,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.shopping.merchant.accounts_v1beta.AutofeedSettingsServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AutofeedSettingsService", + "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.shopping.merchant.accounts.v1beta.AutofeedSettingsService", + "credentialsType": None, + }, + ) + async def get_autofeed_settings( self, request: Optional[ @@ -281,7 +313,7 @@ async def get_autofeed_settings( 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]]] = (), ) -> autofeedsettings.AutofeedSettings: r"""Retrieves the autofeed settings of an account. @@ -324,8 +356,10 @@ async def sample_get_autofeed_settings(): 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.shopping.merchant_accounts_v1beta.types.AutofeedSettings: @@ -390,7 +424,7 @@ async def update_autofeed_settings( 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]]] = (), ) -> autofeedsettings.AutofeedSettings: r"""Updates the autofeed settings of an account. @@ -444,8 +478,10 @@ async def sample_update_autofeed_settings(): 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.shopping.merchant_accounts_v1beta.types.AutofeedSettings: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/client.py index de84163f566e..7e539b0f9167 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.protobuf import field_mask_pb2 # type: ignore from google.shopping.merchant_accounts_v1beta.types import autofeedsettings @@ -583,6 +593,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( @@ -649,6 +663,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.shopping.merchant.accounts_v1beta.AutofeedSettingsServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AutofeedSettingsService", + "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.shopping.merchant.accounts.v1beta.AutofeedSettingsService", + "credentialsType": None, + }, + ) + def get_autofeed_settings( self, request: Optional[ @@ -658,7 +695,7 @@ def get_autofeed_settings( 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]]] = (), ) -> autofeedsettings.AutofeedSettings: r"""Retrieves the autofeed settings of an account. @@ -701,8 +738,10 @@ def sample_get_autofeed_settings(): 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.shopping.merchant_accounts_v1beta.types.AutofeedSettings: @@ -764,7 +803,7 @@ def update_autofeed_settings( 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]]] = (), ) -> autofeedsettings.AutofeedSettings: r"""Updates the autofeed settings of an account. @@ -818,8 +857,10 @@ def sample_update_autofeed_settings(): 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.shopping.merchant_accounts_v1beta.types.AutofeedSettings: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/grpc.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/grpc.py index dbe95388a05c..97e350f27a68 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/grpc.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -20,12 +23,90 @@ 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.shopping.merchant_accounts_v1beta.types import autofeedsettings from .base import DEFAULT_CLIENT_INFO, AutofeedSettingsServiceTransport +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.shopping.merchant.accounts.v1beta.AutofeedSettingsService", + "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.shopping.merchant.accounts.v1beta.AutofeedSettingsService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class AutofeedSettingsServiceGrpcTransport(AutofeedSettingsServiceTransport): """gRPC backend transport for AutofeedSettingsService. @@ -181,7 +262,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 @@ -257,7 +343,7 @@ def get_autofeed_settings( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_autofeed_settings" not in self._stubs: - self._stubs["get_autofeed_settings"] = self.grpc_channel.unary_unary( + self._stubs["get_autofeed_settings"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AutofeedSettingsService/GetAutofeedSettings", request_serializer=autofeedsettings.GetAutofeedSettingsRequest.serialize, response_deserializer=autofeedsettings.AutofeedSettings.deserialize, @@ -286,7 +372,7 @@ def update_autofeed_settings( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_autofeed_settings" not in self._stubs: - self._stubs["update_autofeed_settings"] = self.grpc_channel.unary_unary( + self._stubs["update_autofeed_settings"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AutofeedSettingsService/UpdateAutofeedSettings", request_serializer=autofeedsettings.UpdateAutofeedSettingsRequest.serialize, response_deserializer=autofeedsettings.AutofeedSettings.deserialize, @@ -294,7 +380,7 @@ def update_autofeed_settings( return self._stubs["update_autofeed_settings"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/grpc_asyncio.py index 8a3be82e594e..038d5a647270 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -22,14 +25,93 @@ 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 from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_accounts_v1beta.types import autofeedsettings from .base import DEFAULT_CLIENT_INFO, AutofeedSettingsServiceTransport from .grpc import AutofeedSettingsServiceGrpcTransport +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.shopping.merchant.accounts.v1beta.AutofeedSettingsService", + "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.shopping.merchant.accounts.v1beta.AutofeedSettingsService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class AutofeedSettingsServiceGrpcAsyncIOTransport(AutofeedSettingsServiceTransport): """gRPC AsyncIO backend transport for AutofeedSettingsService. @@ -228,10 +310,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 @@ -266,7 +351,7 @@ def get_autofeed_settings( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_autofeed_settings" not in self._stubs: - self._stubs["get_autofeed_settings"] = self.grpc_channel.unary_unary( + self._stubs["get_autofeed_settings"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AutofeedSettingsService/GetAutofeedSettings", request_serializer=autofeedsettings.GetAutofeedSettingsRequest.serialize, response_deserializer=autofeedsettings.AutofeedSettings.deserialize, @@ -295,7 +380,7 @@ def update_autofeed_settings( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_autofeed_settings" not in self._stubs: - self._stubs["update_autofeed_settings"] = self.grpc_channel.unary_unary( + self._stubs["update_autofeed_settings"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.AutofeedSettingsService/UpdateAutofeedSettings", request_serializer=autofeedsettings.UpdateAutofeedSettingsRequest.serialize, response_deserializer=autofeedsettings.AutofeedSettings.deserialize, @@ -323,7 +408,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/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/rest.py index 286471f99b66..c2b1813251d5 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -37,6 +37,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, @@ -85,8 +93,11 @@ def post_update_autofeed_settings(self, response): def pre_get_autofeed_settings( self, request: autofeedsettings.GetAutofeedSettingsRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[autofeedsettings.GetAutofeedSettingsRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + autofeedsettings.GetAutofeedSettingsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: """Pre-rpc interceptor for get_autofeed_settings Override in a subclass to manipulate the request or metadata @@ -108,9 +119,10 @@ def post_get_autofeed_settings( def pre_update_autofeed_settings( self, request: autofeedsettings.UpdateAutofeedSettingsRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - autofeedsettings.UpdateAutofeedSettingsRequest, Sequence[Tuple[str, str]] + autofeedsettings.UpdateAutofeedSettingsRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for update_autofeed_settings @@ -254,7 +266,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]]] = (), ) -> autofeedsettings.AutofeedSettings: r"""Call the get autofeed settings method over HTTP. @@ -264,8 +276,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: ~.autofeedsettings.AutofeedSettings: @@ -278,6 +292,7 @@ def __call__( http_options = ( _BaseAutofeedSettingsServiceRestTransport._BaseGetAutofeedSettings._get_http_options() ) + request, metadata = self._interceptor.pre_get_autofeed_settings( request, metadata ) @@ -290,6 +305,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.shopping.merchant.accounts_v1beta.AutofeedSettingsServiceClient.GetAutofeedSettings", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AutofeedSettingsService", + "rpcName": "GetAutofeedSettings", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ( AutofeedSettingsServiceRestTransport._GetAutofeedSettings._get_response( @@ -312,7 +354,31 @@ def __call__( pb_resp = autofeedsettings.AutofeedSettings.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_autofeed_settings(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = autofeedsettings.AutofeedSettings.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.shopping.merchant.accounts_v1beta.AutofeedSettingsServiceClient.get_autofeed_settings", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AutofeedSettingsService", + "rpcName": "GetAutofeedSettings", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _UpdateAutofeedSettings( @@ -351,7 +417,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]]] = (), ) -> autofeedsettings.AutofeedSettings: r"""Call the update autofeed settings method over HTTP. @@ -362,8 +428,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: ~.autofeedsettings.AutofeedSettings: @@ -376,6 +444,7 @@ def __call__( http_options = ( _BaseAutofeedSettingsServiceRestTransport._BaseUpdateAutofeedSettings._get_http_options() ) + request, metadata = self._interceptor.pre_update_autofeed_settings( request, metadata ) @@ -392,6 +461,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.shopping.merchant.accounts_v1beta.AutofeedSettingsServiceClient.UpdateAutofeedSettings", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AutofeedSettingsService", + "rpcName": "UpdateAutofeedSettings", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = AutofeedSettingsServiceRestTransport._UpdateAutofeedSettings._get_response( self._host, @@ -413,7 +509,31 @@ def __call__( pb_resp = autofeedsettings.AutofeedSettings.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_autofeed_settings(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = autofeedsettings.AutofeedSettings.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.shopping.merchant.accounts_v1beta.AutofeedSettingsServiceClient.update_autofeed_settings", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.AutofeedSettingsService", + "rpcName": "UpdateAutofeedSettings", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/async_client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/async_client.py index 0961ffbb5ccc..fa62da4addea 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/async_client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -50,6 +51,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, BusinessIdentityServiceTransport from .transports.grpc_asyncio import BusinessIdentityServiceGrpcAsyncIOTransport +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 BusinessIdentityServiceAsyncClient: """Service to support `business @@ -272,6 +282,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.shopping.merchant.accounts_v1beta.BusinessIdentityServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.BusinessIdentityService", + "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.shopping.merchant.accounts.v1beta.BusinessIdentityService", + "credentialsType": None, + }, + ) + async def get_business_identity( self, request: Optional[ @@ -281,7 +313,7 @@ async def get_business_identity( 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]]] = (), ) -> businessidentity.BusinessIdentity: r"""Retrieves the business identity of an account. @@ -324,8 +356,10 @@ async def sample_get_business_identity(): 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.shopping.merchant_accounts_v1beta.types.BusinessIdentity: @@ -389,7 +423,7 @@ async def update_business_identity( 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]]] = (), ) -> businessidentity.BusinessIdentity: r"""Updates the business identity of an account. Executing this method requires admin access. @@ -440,8 +474,10 @@ async def sample_update_business_identity(): 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.shopping.merchant_accounts_v1beta.types.BusinessIdentity: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/client.py index ec0da6d3ff28..2dc21c12dd3d 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.protobuf import field_mask_pb2 # type: ignore from google.shopping.merchant_accounts_v1beta.types import businessidentity @@ -583,6 +593,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( @@ -649,6 +663,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.shopping.merchant.accounts_v1beta.BusinessIdentityServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.BusinessIdentityService", + "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.shopping.merchant.accounts.v1beta.BusinessIdentityService", + "credentialsType": None, + }, + ) + def get_business_identity( self, request: Optional[ @@ -658,7 +695,7 @@ def get_business_identity( 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]]] = (), ) -> businessidentity.BusinessIdentity: r"""Retrieves the business identity of an account. @@ -701,8 +738,10 @@ def sample_get_business_identity(): 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.shopping.merchant_accounts_v1beta.types.BusinessIdentity: @@ -763,7 +802,7 @@ def update_business_identity( 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]]] = (), ) -> businessidentity.BusinessIdentity: r"""Updates the business identity of an account. Executing this method requires admin access. @@ -814,8 +853,10 @@ def sample_update_business_identity(): 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.shopping.merchant_accounts_v1beta.types.BusinessIdentity: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/grpc.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/grpc.py index eea782c1b6f9..1fb80e27ed79 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/grpc.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -20,12 +23,90 @@ 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.shopping.merchant_accounts_v1beta.types import businessidentity from .base import DEFAULT_CLIENT_INFO, BusinessIdentityServiceTransport +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.shopping.merchant.accounts.v1beta.BusinessIdentityService", + "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.shopping.merchant.accounts.v1beta.BusinessIdentityService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class BusinessIdentityServiceGrpcTransport(BusinessIdentityServiceTransport): """gRPC backend transport for BusinessIdentityService. @@ -181,7 +262,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 @@ -257,7 +343,7 @@ def get_business_identity( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_business_identity" not in self._stubs: - self._stubs["get_business_identity"] = self.grpc_channel.unary_unary( + self._stubs["get_business_identity"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.BusinessIdentityService/GetBusinessIdentity", request_serializer=businessidentity.GetBusinessIdentityRequest.serialize, response_deserializer=businessidentity.BusinessIdentity.deserialize, @@ -287,7 +373,7 @@ def update_business_identity( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_business_identity" not in self._stubs: - self._stubs["update_business_identity"] = self.grpc_channel.unary_unary( + self._stubs["update_business_identity"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.BusinessIdentityService/UpdateBusinessIdentity", request_serializer=businessidentity.UpdateBusinessIdentityRequest.serialize, response_deserializer=businessidentity.BusinessIdentity.deserialize, @@ -295,7 +381,7 @@ def update_business_identity( return self._stubs["update_business_identity"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/grpc_asyncio.py index cef1a65f4404..33fec1947411 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -22,14 +25,93 @@ 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 from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_accounts_v1beta.types import businessidentity from .base import DEFAULT_CLIENT_INFO, BusinessIdentityServiceTransport from .grpc import BusinessIdentityServiceGrpcTransport +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.shopping.merchant.accounts.v1beta.BusinessIdentityService", + "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.shopping.merchant.accounts.v1beta.BusinessIdentityService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class BusinessIdentityServiceGrpcAsyncIOTransport(BusinessIdentityServiceTransport): """gRPC AsyncIO backend transport for BusinessIdentityService. @@ -228,10 +310,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 @@ -266,7 +351,7 @@ def get_business_identity( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_business_identity" not in self._stubs: - self._stubs["get_business_identity"] = self.grpc_channel.unary_unary( + self._stubs["get_business_identity"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.BusinessIdentityService/GetBusinessIdentity", request_serializer=businessidentity.GetBusinessIdentityRequest.serialize, response_deserializer=businessidentity.BusinessIdentity.deserialize, @@ -296,7 +381,7 @@ def update_business_identity( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_business_identity" not in self._stubs: - self._stubs["update_business_identity"] = self.grpc_channel.unary_unary( + self._stubs["update_business_identity"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.BusinessIdentityService/UpdateBusinessIdentity", request_serializer=businessidentity.UpdateBusinessIdentityRequest.serialize, response_deserializer=businessidentity.BusinessIdentity.deserialize, @@ -324,7 +409,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/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/rest.py index 676645a4e162..56639f05a5cf 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -37,6 +37,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, @@ -85,8 +93,11 @@ def post_update_business_identity(self, response): def pre_get_business_identity( self, request: businessidentity.GetBusinessIdentityRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[businessidentity.GetBusinessIdentityRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + businessidentity.GetBusinessIdentityRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: """Pre-rpc interceptor for get_business_identity Override in a subclass to manipulate the request or metadata @@ -108,9 +119,10 @@ def post_get_business_identity( def pre_update_business_identity( self, request: businessidentity.UpdateBusinessIdentityRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - businessidentity.UpdateBusinessIdentityRequest, Sequence[Tuple[str, str]] + businessidentity.UpdateBusinessIdentityRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for update_business_identity @@ -254,7 +266,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]]] = (), ) -> businessidentity.BusinessIdentity: r"""Call the get business identity method over HTTP. @@ -264,8 +276,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: ~.businessidentity.BusinessIdentity: @@ -277,6 +291,7 @@ def __call__( http_options = ( _BaseBusinessIdentityServiceRestTransport._BaseGetBusinessIdentity._get_http_options() ) + request, metadata = self._interceptor.pre_get_business_identity( request, metadata ) @@ -289,6 +304,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.shopping.merchant.accounts_v1beta.BusinessIdentityServiceClient.GetBusinessIdentity", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.BusinessIdentityService", + "rpcName": "GetBusinessIdentity", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ( BusinessIdentityServiceRestTransport._GetBusinessIdentity._get_response( @@ -311,7 +353,31 @@ def __call__( pb_resp = businessidentity.BusinessIdentity.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_business_identity(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = businessidentity.BusinessIdentity.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.shopping.merchant.accounts_v1beta.BusinessIdentityServiceClient.get_business_identity", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.BusinessIdentityService", + "rpcName": "GetBusinessIdentity", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _UpdateBusinessIdentity( @@ -350,7 +416,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]]] = (), ) -> businessidentity.BusinessIdentity: r"""Call the update business identity method over HTTP. @@ -361,8 +427,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: ~.businessidentity.BusinessIdentity: @@ -374,6 +442,7 @@ def __call__( http_options = ( _BaseBusinessIdentityServiceRestTransport._BaseUpdateBusinessIdentity._get_http_options() ) + request, metadata = self._interceptor.pre_update_business_identity( request, metadata ) @@ -390,6 +459,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.shopping.merchant.accounts_v1beta.BusinessIdentityServiceClient.UpdateBusinessIdentity", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.BusinessIdentityService", + "rpcName": "UpdateBusinessIdentity", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = BusinessIdentityServiceRestTransport._UpdateBusinessIdentity._get_response( self._host, @@ -411,7 +507,31 @@ def __call__( pb_resp = businessidentity.BusinessIdentity.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_business_identity(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = businessidentity.BusinessIdentity.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.shopping.merchant.accounts_v1beta.BusinessIdentityServiceClient.update_business_identity", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.BusinessIdentityService", + "rpcName": "UpdateBusinessIdentity", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/async_client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/async_client.py index 470d273018fa..cb2ca9f69deb 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/async_client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -56,6 +57,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, BusinessInfoServiceTransport from .transports.grpc_asyncio import BusinessInfoServiceGrpcAsyncIOTransport +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 BusinessInfoServiceAsyncClient: """Service to support business info API.""" @@ -267,6 +277,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.shopping.merchant.accounts_v1beta.BusinessInfoServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.BusinessInfoService", + "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.shopping.merchant.accounts.v1beta.BusinessInfoService", + "credentialsType": None, + }, + ) + async def get_business_info( self, request: Optional[Union[businessinfo.GetBusinessInfoRequest, dict]] = None, @@ -274,7 +306,7 @@ async def get_business_info( 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]]] = (), ) -> businessinfo.BusinessInfo: r"""Retrieves the business info of an account. @@ -317,8 +349,10 @@ async def sample_get_business_info(): 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.shopping.merchant_accounts_v1beta.types.BusinessInfo: @@ -380,7 +414,7 @@ async def update_business_info( 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]]] = (), ) -> businessinfo.BusinessInfo: r"""Updates the business info of an account. Executing this method requires admin access. @@ -430,8 +464,10 @@ async def sample_update_business_info(): 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.shopping.merchant_accounts_v1beta.types.BusinessInfo: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/client.py index cede5fac296a..78fc2fa851ff 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.protobuf import field_mask_pb2 # type: ignore from google.type import phone_number_pb2 # type: ignore from google.type import postal_address_pb2 # type: ignore @@ -582,6 +592,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( @@ -648,6 +662,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.shopping.merchant.accounts_v1beta.BusinessInfoServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.BusinessInfoService", + "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.shopping.merchant.accounts.v1beta.BusinessInfoService", + "credentialsType": None, + }, + ) + def get_business_info( self, request: Optional[Union[businessinfo.GetBusinessInfoRequest, dict]] = None, @@ -655,7 +692,7 @@ def get_business_info( 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]]] = (), ) -> businessinfo.BusinessInfo: r"""Retrieves the business info of an account. @@ -698,8 +735,10 @@ def sample_get_business_info(): 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.shopping.merchant_accounts_v1beta.types.BusinessInfo: @@ -758,7 +797,7 @@ def update_business_info( 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]]] = (), ) -> businessinfo.BusinessInfo: r"""Updates the business info of an account. Executing this method requires admin access. @@ -808,8 +847,10 @@ def sample_update_business_info(): 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.shopping.merchant_accounts_v1beta.types.BusinessInfo: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/grpc.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/grpc.py index b77bab780f35..e08ebbf7b6d2 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/grpc.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -20,12 +23,90 @@ 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.shopping.merchant_accounts_v1beta.types import businessinfo from .base import DEFAULT_CLIENT_INFO, BusinessInfoServiceTransport +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.shopping.merchant.accounts.v1beta.BusinessInfoService", + "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.shopping.merchant.accounts.v1beta.BusinessInfoService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class BusinessInfoServiceGrpcTransport(BusinessInfoServiceTransport): """gRPC backend transport for BusinessInfoService. @@ -179,7 +260,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 @@ -253,7 +339,7 @@ def get_business_info( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_business_info" not in self._stubs: - self._stubs["get_business_info"] = self.grpc_channel.unary_unary( + self._stubs["get_business_info"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.BusinessInfoService/GetBusinessInfo", request_serializer=businessinfo.GetBusinessInfoRequest.serialize, response_deserializer=businessinfo.BusinessInfo.deserialize, @@ -280,7 +366,7 @@ def update_business_info( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_business_info" not in self._stubs: - self._stubs["update_business_info"] = self.grpc_channel.unary_unary( + self._stubs["update_business_info"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.BusinessInfoService/UpdateBusinessInfo", request_serializer=businessinfo.UpdateBusinessInfoRequest.serialize, response_deserializer=businessinfo.BusinessInfo.deserialize, @@ -288,7 +374,7 @@ def update_business_info( return self._stubs["update_business_info"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/grpc_asyncio.py index e1c608c2ad30..c767585e9b0a 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -22,14 +25,93 @@ 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 from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_accounts_v1beta.types import businessinfo from .base import DEFAULT_CLIENT_INFO, BusinessInfoServiceTransport from .grpc import BusinessInfoServiceGrpcTransport +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.shopping.merchant.accounts.v1beta.BusinessInfoService", + "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.shopping.merchant.accounts.v1beta.BusinessInfoService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class BusinessInfoServiceGrpcAsyncIOTransport(BusinessInfoServiceTransport): """gRPC AsyncIO backend transport for BusinessInfoService. @@ -226,10 +308,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 @@ -263,7 +348,7 @@ def get_business_info( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_business_info" not in self._stubs: - self._stubs["get_business_info"] = self.grpc_channel.unary_unary( + self._stubs["get_business_info"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.BusinessInfoService/GetBusinessInfo", request_serializer=businessinfo.GetBusinessInfoRequest.serialize, response_deserializer=businessinfo.BusinessInfo.deserialize, @@ -292,7 +377,7 @@ def update_business_info( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_business_info" not in self._stubs: - self._stubs["update_business_info"] = self.grpc_channel.unary_unary( + self._stubs["update_business_info"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.BusinessInfoService/UpdateBusinessInfo", request_serializer=businessinfo.UpdateBusinessInfoRequest.serialize, response_deserializer=businessinfo.BusinessInfo.deserialize, @@ -320,7 +405,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/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/rest.py index 7de136978256..27e29fd0e255 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -37,6 +37,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, @@ -85,8 +93,10 @@ def post_update_business_info(self, response): def pre_get_business_info( self, request: businessinfo.GetBusinessInfoRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[businessinfo.GetBusinessInfoRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + businessinfo.GetBusinessInfoRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for get_business_info Override in a subclass to manipulate the request or metadata @@ -108,8 +118,10 @@ def post_get_business_info( def pre_update_business_info( self, request: businessinfo.UpdateBusinessInfoRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[businessinfo.UpdateBusinessInfoRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + businessinfo.UpdateBusinessInfoRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for update_business_info Override in a subclass to manipulate the request or metadata @@ -250,7 +262,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]]] = (), ) -> businessinfo.BusinessInfo: r"""Call the get business info method over HTTP. @@ -260,8 +272,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: ~.businessinfo.BusinessInfo: @@ -273,6 +287,7 @@ def __call__( http_options = ( _BaseBusinessInfoServiceRestTransport._BaseGetBusinessInfo._get_http_options() ) + request, metadata = self._interceptor.pre_get_business_info( request, metadata ) @@ -285,6 +300,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.shopping.merchant.accounts_v1beta.BusinessInfoServiceClient.GetBusinessInfo", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.BusinessInfoService", + "rpcName": "GetBusinessInfo", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = BusinessInfoServiceRestTransport._GetBusinessInfo._get_response( self._host, @@ -305,7 +347,29 @@ def __call__( pb_resp = businessinfo.BusinessInfo.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_business_info(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = businessinfo.BusinessInfo.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.shopping.merchant.accounts_v1beta.BusinessInfoServiceClient.get_business_info", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.BusinessInfoService", + "rpcName": "GetBusinessInfo", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _UpdateBusinessInfo( @@ -344,7 +408,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]]] = (), ) -> businessinfo.BusinessInfo: r"""Call the update business info method over HTTP. @@ -354,8 +418,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: ~.businessinfo.BusinessInfo: @@ -367,6 +433,7 @@ def __call__( http_options = ( _BaseBusinessInfoServiceRestTransport._BaseUpdateBusinessInfo._get_http_options() ) + request, metadata = self._interceptor.pre_update_business_info( request, metadata ) @@ -383,6 +450,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.shopping.merchant.accounts_v1beta.BusinessInfoServiceClient.UpdateBusinessInfo", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.BusinessInfoService", + "rpcName": "UpdateBusinessInfo", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ( BusinessInfoServiceRestTransport._UpdateBusinessInfo._get_response( @@ -406,7 +500,29 @@ def __call__( pb_resp = businessinfo.BusinessInfo.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_business_info(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = businessinfo.BusinessInfo.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.shopping.merchant.accounts_v1beta.BusinessInfoServiceClient.update_business_info", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.BusinessInfoService", + "rpcName": "UpdateBusinessInfo", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/async_client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/async_client.py index 024febb291db..79f1ddd99f91 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/async_client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -50,6 +51,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, EmailPreferencesServiceTransport from .transports.grpc_asyncio import EmailPreferencesServiceGrpcAsyncIOTransport +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 EmailPreferencesServiceAsyncClient: """Service to support the ``EmailPreferences`` API. @@ -273,6 +283,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.shopping.merchant.accounts_v1beta.EmailPreferencesServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.EmailPreferencesService", + "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.shopping.merchant.accounts.v1beta.EmailPreferencesService", + "credentialsType": None, + }, + ) + async def get_email_preferences( self, request: Optional[ @@ -282,7 +314,7 @@ async def get_email_preferences( 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]]] = (), ) -> emailpreferences.EmailPreferences: r"""Returns the email preferences for a Merchant Center account user. @@ -331,8 +363,10 @@ async def sample_get_email_preferences(): 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.shopping.merchant_accounts_v1beta.types.EmailPreferences: @@ -399,7 +433,7 @@ async def update_email_preferences( 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]]] = (), ) -> emailpreferences.EmailPreferences: r"""Updates the email preferences for a Merchant Center account user. MCA users should specify the MCA account rather than a @@ -460,8 +494,10 @@ async def sample_update_email_preferences(): 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.shopping.merchant_accounts_v1beta.types.EmailPreferences: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/client.py index c0c5ae0e2911..db65e710fa86 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.protobuf import field_mask_pb2 # type: ignore from google.shopping.merchant_accounts_v1beta.types import emailpreferences @@ -588,6 +598,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( @@ -654,6 +668,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.shopping.merchant.accounts_v1beta.EmailPreferencesServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.EmailPreferencesService", + "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.shopping.merchant.accounts.v1beta.EmailPreferencesService", + "credentialsType": None, + }, + ) + def get_email_preferences( self, request: Optional[ @@ -663,7 +700,7 @@ def get_email_preferences( 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]]] = (), ) -> emailpreferences.EmailPreferences: r"""Returns the email preferences for a Merchant Center account user. @@ -712,8 +749,10 @@ def sample_get_email_preferences(): 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.shopping.merchant_accounts_v1beta.types.EmailPreferences: @@ -777,7 +816,7 @@ def update_email_preferences( 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]]] = (), ) -> emailpreferences.EmailPreferences: r"""Updates the email preferences for a Merchant Center account user. MCA users should specify the MCA account rather than a @@ -838,8 +877,10 @@ def sample_update_email_preferences(): 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.shopping.merchant_accounts_v1beta.types.EmailPreferences: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/grpc.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/grpc.py index 79b98addeaa5..ec91f5e79ac0 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/grpc.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -20,12 +23,90 @@ 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.shopping.merchant_accounts_v1beta.types import emailpreferences from .base import DEFAULT_CLIENT_INFO, EmailPreferencesServiceTransport +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.shopping.merchant.accounts.v1beta.EmailPreferencesService", + "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.shopping.merchant.accounts.v1beta.EmailPreferencesService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class EmailPreferencesServiceGrpcTransport(EmailPreferencesServiceTransport): """gRPC backend transport for EmailPreferencesService. @@ -182,7 +263,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 @@ -262,7 +348,7 @@ def get_email_preferences( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_email_preferences" not in self._stubs: - self._stubs["get_email_preferences"] = self.grpc_channel.unary_unary( + self._stubs["get_email_preferences"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.EmailPreferencesService/GetEmailPreferences", request_serializer=emailpreferences.GetEmailPreferencesRequest.serialize, response_deserializer=emailpreferences.EmailPreferences.deserialize, @@ -302,7 +388,7 @@ def update_email_preferences( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_email_preferences" not in self._stubs: - self._stubs["update_email_preferences"] = self.grpc_channel.unary_unary( + self._stubs["update_email_preferences"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.EmailPreferencesService/UpdateEmailPreferences", request_serializer=emailpreferences.UpdateEmailPreferencesRequest.serialize, response_deserializer=emailpreferences.EmailPreferences.deserialize, @@ -310,7 +396,7 @@ def update_email_preferences( return self._stubs["update_email_preferences"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/grpc_asyncio.py index 650ebee527de..2f5a29bc3758 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -22,14 +25,93 @@ 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 from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_accounts_v1beta.types import emailpreferences from .base import DEFAULT_CLIENT_INFO, EmailPreferencesServiceTransport from .grpc import EmailPreferencesServiceGrpcTransport +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.shopping.merchant.accounts.v1beta.EmailPreferencesService", + "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.shopping.merchant.accounts.v1beta.EmailPreferencesService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class EmailPreferencesServiceGrpcAsyncIOTransport(EmailPreferencesServiceTransport): """gRPC AsyncIO backend transport for EmailPreferencesService. @@ -229,10 +311,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 @@ -271,7 +356,7 @@ def get_email_preferences( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_email_preferences" not in self._stubs: - self._stubs["get_email_preferences"] = self.grpc_channel.unary_unary( + self._stubs["get_email_preferences"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.EmailPreferencesService/GetEmailPreferences", request_serializer=emailpreferences.GetEmailPreferencesRequest.serialize, response_deserializer=emailpreferences.EmailPreferences.deserialize, @@ -311,7 +396,7 @@ def update_email_preferences( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_email_preferences" not in self._stubs: - self._stubs["update_email_preferences"] = self.grpc_channel.unary_unary( + self._stubs["update_email_preferences"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.EmailPreferencesService/UpdateEmailPreferences", request_serializer=emailpreferences.UpdateEmailPreferencesRequest.serialize, response_deserializer=emailpreferences.EmailPreferences.deserialize, @@ -339,7 +424,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/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/rest.py index 42876f3e5661..28c774418566 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -37,6 +37,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, @@ -85,8 +93,11 @@ def post_update_email_preferences(self, response): def pre_get_email_preferences( self, request: emailpreferences.GetEmailPreferencesRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[emailpreferences.GetEmailPreferencesRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + emailpreferences.GetEmailPreferencesRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: """Pre-rpc interceptor for get_email_preferences Override in a subclass to manipulate the request or metadata @@ -108,9 +119,10 @@ def post_get_email_preferences( def pre_update_email_preferences( self, request: emailpreferences.UpdateEmailPreferencesRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - emailpreferences.UpdateEmailPreferencesRequest, Sequence[Tuple[str, str]] + emailpreferences.UpdateEmailPreferencesRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for update_email_preferences @@ -255,7 +267,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]]] = (), ) -> emailpreferences.EmailPreferences: r"""Call the get email preferences method over HTTP. @@ -266,8 +278,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: ~.emailpreferences.EmailPreferences: @@ -282,6 +296,7 @@ def __call__( http_options = ( _BaseEmailPreferencesServiceRestTransport._BaseGetEmailPreferences._get_http_options() ) + request, metadata = self._interceptor.pre_get_email_preferences( request, metadata ) @@ -294,6 +309,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.shopping.merchant.accounts_v1beta.EmailPreferencesServiceClient.GetEmailPreferences", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.EmailPreferencesService", + "rpcName": "GetEmailPreferences", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ( EmailPreferencesServiceRestTransport._GetEmailPreferences._get_response( @@ -316,7 +358,31 @@ def __call__( pb_resp = emailpreferences.EmailPreferences.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_email_preferences(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = emailpreferences.EmailPreferences.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.shopping.merchant.accounts_v1beta.EmailPreferencesServiceClient.get_email_preferences", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.EmailPreferencesService", + "rpcName": "GetEmailPreferences", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _UpdateEmailPreferences( @@ -355,7 +421,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]]] = (), ) -> emailpreferences.EmailPreferences: r"""Call the update email preferences method over HTTP. @@ -366,8 +432,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: ~.emailpreferences.EmailPreferences: @@ -382,6 +450,7 @@ def __call__( http_options = ( _BaseEmailPreferencesServiceRestTransport._BaseUpdateEmailPreferences._get_http_options() ) + request, metadata = self._interceptor.pre_update_email_preferences( request, metadata ) @@ -398,6 +467,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.shopping.merchant.accounts_v1beta.EmailPreferencesServiceClient.UpdateEmailPreferences", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.EmailPreferencesService", + "rpcName": "UpdateEmailPreferences", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = EmailPreferencesServiceRestTransport._UpdateEmailPreferences._get_response( self._host, @@ -419,7 +515,31 @@ def __call__( pb_resp = emailpreferences.EmailPreferences.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_email_preferences(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = emailpreferences.EmailPreferences.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.shopping.merchant.accounts_v1beta.EmailPreferencesServiceClient.update_email_preferences", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.EmailPreferencesService", + "rpcName": "UpdateEmailPreferences", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/async_client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/async_client.py index 54e31ed88a03..d0c05fe4a457 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/async_client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -51,6 +52,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, HomepageServiceTransport from .transports.grpc_asyncio import HomepageServiceGrpcAsyncIOTransport +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 HomepageServiceAsyncClient: """Service to support an API for a store's homepage.""" @@ -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.shopping.merchant.accounts_v1beta.HomepageServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.HomepageService", + "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.shopping.merchant.accounts.v1beta.HomepageService", + "credentialsType": None, + }, + ) + async def get_homepage( self, request: Optional[Union[homepage.GetHomepageRequest, dict]] = None, @@ -265,7 +297,7 @@ async def get_homepage( 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]]] = (), ) -> homepage.Homepage: r"""Retrieves a store's homepage. @@ -308,8 +340,10 @@ async def sample_get_homepage(): 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.shopping.merchant_accounts_v1beta.types.Homepage: @@ -369,7 +403,7 @@ async def update_homepage( 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]]] = (), ) -> gsma_homepage.Homepage: r"""Updates a store's homepage. Executing this method requires admin access. @@ -419,8 +453,10 @@ async def sample_update_homepage(): 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.shopping.merchant_accounts_v1beta.types.Homepage: @@ -482,7 +518,7 @@ async def claim_homepage( *, 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]]] = (), ) -> homepage.Homepage: r"""Claims a store's homepage. Executing this method requires admin access. @@ -530,8 +566,10 @@ async def sample_claim_homepage(): 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.shopping.merchant_accounts_v1beta.types.Homepage: @@ -575,7 +613,7 @@ async def unclaim_homepage( *, 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]]] = (), ) -> homepage.Homepage: r"""Unclaims a store's homepage. Executing this method requires admin access. @@ -612,8 +650,10 @@ async def sample_unclaim_homepage(): 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.shopping.merchant_accounts_v1beta.types.Homepage: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/client.py index feba2a7d395c..358914a9dece 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.protobuf import field_mask_pb2 # type: ignore from google.shopping.merchant_accounts_v1beta.types import homepage as gsma_homepage @@ -575,6 +585,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( @@ -640,6 +654,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.shopping.merchant.accounts_v1beta.HomepageServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.HomepageService", + "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.shopping.merchant.accounts.v1beta.HomepageService", + "credentialsType": None, + }, + ) + def get_homepage( self, request: Optional[Union[homepage.GetHomepageRequest, dict]] = None, @@ -647,7 +684,7 @@ def get_homepage( 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]]] = (), ) -> homepage.Homepage: r"""Retrieves a store's homepage. @@ -690,8 +727,10 @@ def sample_get_homepage(): 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.shopping.merchant_accounts_v1beta.types.Homepage: @@ -748,7 +787,7 @@ def update_homepage( 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]]] = (), ) -> gsma_homepage.Homepage: r"""Updates a store's homepage. Executing this method requires admin access. @@ -798,8 +837,10 @@ def sample_update_homepage(): 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.shopping.merchant_accounts_v1beta.types.Homepage: @@ -858,7 +899,7 @@ def claim_homepage( *, 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]]] = (), ) -> homepage.Homepage: r"""Claims a store's homepage. Executing this method requires admin access. @@ -906,8 +947,10 @@ def sample_claim_homepage(): 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.shopping.merchant_accounts_v1beta.types.Homepage: @@ -949,7 +992,7 @@ def unclaim_homepage( *, 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]]] = (), ) -> homepage.Homepage: r"""Unclaims a store's homepage. Executing this method requires admin access. @@ -986,8 +1029,10 @@ def sample_unclaim_homepage(): 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.shopping.merchant_accounts_v1beta.types.Homepage: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/grpc.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/grpc.py index 8b9a4a317a7d..464fc04a181b 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/grpc.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -20,13 +23,91 @@ 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.shopping.merchant_accounts_v1beta.types import homepage as gsma_homepage from google.shopping.merchant_accounts_v1beta.types import homepage from .base import DEFAULT_CLIENT_INFO, HomepageServiceTransport +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.shopping.merchant.accounts.v1beta.HomepageService", + "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.shopping.merchant.accounts.v1beta.HomepageService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class HomepageServiceGrpcTransport(HomepageServiceTransport): """gRPC backend transport for HomepageService. @@ -180,7 +261,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 @@ -254,7 +340,7 @@ def get_homepage( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_homepage" not in self._stubs: - self._stubs["get_homepage"] = self.grpc_channel.unary_unary( + self._stubs["get_homepage"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.HomepageService/GetHomepage", request_serializer=homepage.GetHomepageRequest.serialize, response_deserializer=homepage.Homepage.deserialize, @@ -281,7 +367,7 @@ def update_homepage( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_homepage" not in self._stubs: - self._stubs["update_homepage"] = self.grpc_channel.unary_unary( + self._stubs["update_homepage"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.HomepageService/UpdateHomepage", request_serializer=gsma_homepage.UpdateHomepageRequest.serialize, response_deserializer=gsma_homepage.Homepage.deserialize, @@ -319,7 +405,7 @@ def claim_homepage( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "claim_homepage" not in self._stubs: - self._stubs["claim_homepage"] = self.grpc_channel.unary_unary( + self._stubs["claim_homepage"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.HomepageService/ClaimHomepage", request_serializer=homepage.ClaimHomepageRequest.serialize, response_deserializer=homepage.Homepage.deserialize, @@ -346,7 +432,7 @@ def unclaim_homepage( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "unclaim_homepage" not in self._stubs: - self._stubs["unclaim_homepage"] = self.grpc_channel.unary_unary( + self._stubs["unclaim_homepage"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.HomepageService/UnclaimHomepage", request_serializer=homepage.UnclaimHomepageRequest.serialize, response_deserializer=homepage.Homepage.deserialize, @@ -354,7 +440,7 @@ def unclaim_homepage( return self._stubs["unclaim_homepage"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/grpc_asyncio.py index b6a09e6a7af3..53f9c814bc1a 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -22,8 +25,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 from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_accounts_v1beta.types import homepage as gsma_homepage from google.shopping.merchant_accounts_v1beta.types import homepage @@ -31,6 +37,82 @@ from .base import DEFAULT_CLIENT_INFO, HomepageServiceTransport from .grpc import HomepageServiceGrpcTransport +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.shopping.merchant.accounts.v1beta.HomepageService", + "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.shopping.merchant.accounts.v1beta.HomepageService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class HomepageServiceGrpcAsyncIOTransport(HomepageServiceTransport): """gRPC AsyncIO backend transport for HomepageService. @@ -227,10 +309,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 @@ -262,7 +347,7 @@ def get_homepage( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_homepage" not in self._stubs: - self._stubs["get_homepage"] = self.grpc_channel.unary_unary( + self._stubs["get_homepage"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.HomepageService/GetHomepage", request_serializer=homepage.GetHomepageRequest.serialize, response_deserializer=homepage.Homepage.deserialize, @@ -291,7 +376,7 @@ def update_homepage( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_homepage" not in self._stubs: - self._stubs["update_homepage"] = self.grpc_channel.unary_unary( + self._stubs["update_homepage"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.HomepageService/UpdateHomepage", request_serializer=gsma_homepage.UpdateHomepageRequest.serialize, response_deserializer=gsma_homepage.Homepage.deserialize, @@ -329,7 +414,7 @@ def claim_homepage( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "claim_homepage" not in self._stubs: - self._stubs["claim_homepage"] = self.grpc_channel.unary_unary( + self._stubs["claim_homepage"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.HomepageService/ClaimHomepage", request_serializer=homepage.ClaimHomepageRequest.serialize, response_deserializer=homepage.Homepage.deserialize, @@ -356,7 +441,7 @@ def unclaim_homepage( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "unclaim_homepage" not in self._stubs: - self._stubs["unclaim_homepage"] = self.grpc_channel.unary_unary( + self._stubs["unclaim_homepage"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.HomepageService/UnclaimHomepage", request_serializer=homepage.UnclaimHomepageRequest.serialize, response_deserializer=homepage.Homepage.deserialize, @@ -394,7 +479,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/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/rest.py index 75e036c32d11..f39ea3706937 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -38,6 +38,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, @@ -102,8 +110,8 @@ def post_update_homepage(self, response): def pre_claim_homepage( self, request: homepage.ClaimHomepageRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[homepage.ClaimHomepageRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[homepage.ClaimHomepageRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for claim_homepage Override in a subclass to manipulate the request or metadata @@ -121,8 +129,10 @@ def post_claim_homepage(self, response: homepage.Homepage) -> homepage.Homepage: return response def pre_get_homepage( - self, request: homepage.GetHomepageRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[homepage.GetHomepageRequest, Sequence[Tuple[str, str]]]: + self, + request: homepage.GetHomepageRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[homepage.GetHomepageRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for get_homepage Override in a subclass to manipulate the request or metadata @@ -142,8 +152,10 @@ def post_get_homepage(self, response: homepage.Homepage) -> homepage.Homepage: def pre_unclaim_homepage( self, request: homepage.UnclaimHomepageRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[homepage.UnclaimHomepageRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + homepage.UnclaimHomepageRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for unclaim_homepage Override in a subclass to manipulate the request or metadata @@ -163,8 +175,10 @@ def post_unclaim_homepage(self, response: homepage.Homepage) -> homepage.Homepag def pre_update_homepage( self, request: gsma_homepage.UpdateHomepageRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[gsma_homepage.UpdateHomepageRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gsma_homepage.UpdateHomepageRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for update_homepage Override in a subclass to manipulate the request or metadata @@ -305,7 +319,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]]] = (), ) -> homepage.Homepage: r"""Call the claim homepage method over HTTP. @@ -315,8 +329,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: ~.homepage.Homepage: @@ -326,6 +342,7 @@ def __call__( http_options = ( _BaseHomepageServiceRestTransport._BaseClaimHomepage._get_http_options() ) + request, metadata = self._interceptor.pre_claim_homepage(request, metadata) transcoded_request = _BaseHomepageServiceRestTransport._BaseClaimHomepage._get_transcoded_request( http_options, request @@ -340,6 +357,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.shopping.merchant.accounts_v1beta.HomepageServiceClient.ClaimHomepage", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.HomepageService", + "rpcName": "ClaimHomepage", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = HomepageServiceRestTransport._ClaimHomepage._get_response( self._host, @@ -361,7 +405,29 @@ def __call__( pb_resp = homepage.Homepage.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_claim_homepage(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = homepage.Homepage.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.shopping.merchant.accounts_v1beta.HomepageServiceClient.claim_homepage", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.HomepageService", + "rpcName": "ClaimHomepage", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _GetHomepage( @@ -398,7 +464,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]]] = (), ) -> homepage.Homepage: r"""Call the get homepage method over HTTP. @@ -408,8 +474,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: ~.homepage.Homepage: @@ -419,6 +487,7 @@ def __call__( http_options = ( _BaseHomepageServiceRestTransport._BaseGetHomepage._get_http_options() ) + request, metadata = self._interceptor.pre_get_homepage(request, metadata) transcoded_request = _BaseHomepageServiceRestTransport._BaseGetHomepage._get_transcoded_request( http_options, request @@ -429,6 +498,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.shopping.merchant.accounts_v1beta.HomepageServiceClient.GetHomepage", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.HomepageService", + "rpcName": "GetHomepage", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = HomepageServiceRestTransport._GetHomepage._get_response( self._host, @@ -449,7 +545,29 @@ def __call__( pb_resp = homepage.Homepage.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_homepage(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = homepage.Homepage.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.shopping.merchant.accounts_v1beta.HomepageServiceClient.get_homepage", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.HomepageService", + "rpcName": "GetHomepage", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _UnclaimHomepage( @@ -487,7 +605,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]]] = (), ) -> homepage.Homepage: r"""Call the unclaim homepage method over HTTP. @@ -497,8 +615,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: ~.homepage.Homepage: @@ -508,6 +628,7 @@ def __call__( http_options = ( _BaseHomepageServiceRestTransport._BaseUnclaimHomepage._get_http_options() ) + request, metadata = self._interceptor.pre_unclaim_homepage( request, metadata ) @@ -524,6 +645,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.shopping.merchant.accounts_v1beta.HomepageServiceClient.UnclaimHomepage", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.HomepageService", + "rpcName": "UnclaimHomepage", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = HomepageServiceRestTransport._UnclaimHomepage._get_response( self._host, @@ -545,7 +693,29 @@ def __call__( pb_resp = homepage.Homepage.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_unclaim_homepage(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = homepage.Homepage.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.shopping.merchant.accounts_v1beta.HomepageServiceClient.unclaim_homepage", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.HomepageService", + "rpcName": "UnclaimHomepage", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _UpdateHomepage( @@ -583,7 +753,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]]] = (), ) -> gsma_homepage.Homepage: r"""Call the update homepage method over HTTP. @@ -593,8 +763,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: ~.gsma_homepage.Homepage: @@ -604,6 +776,7 @@ def __call__( http_options = ( _BaseHomepageServiceRestTransport._BaseUpdateHomepage._get_http_options() ) + request, metadata = self._interceptor.pre_update_homepage(request, metadata) transcoded_request = _BaseHomepageServiceRestTransport._BaseUpdateHomepage._get_transcoded_request( http_options, request @@ -618,6 +791,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.shopping.merchant.accounts_v1beta.HomepageServiceClient.UpdateHomepage", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.HomepageService", + "rpcName": "UpdateHomepage", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = HomepageServiceRestTransport._UpdateHomepage._get_response( self._host, @@ -639,7 +839,29 @@ def __call__( pb_resp = gsma_homepage.Homepage.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_homepage(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = gsma_homepage.Homepage.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.shopping.merchant.accounts_v1beta.HomepageServiceClient.update_homepage", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.HomepageService", + "rpcName": "UpdateHomepage", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/async_client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/async_client.py index 8806d4a0a30f..eb71baa2a690 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/async_client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -51,6 +52,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, OnlineReturnPolicyServiceTransport from .transports.grpc_asyncio import OnlineReturnPolicyServiceGrpcAsyncIOTransport +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 OnlineReturnPolicyServiceAsyncClient: """The service facilitates the management of a merchant's remorse @@ -278,6 +288,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.shopping.merchant.accounts_v1beta.OnlineReturnPolicyServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.OnlineReturnPolicyService", + "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.shopping.merchant.accounts.v1beta.OnlineReturnPolicyService", + "credentialsType": None, + }, + ) + async def get_online_return_policy( self, request: Optional[ @@ -287,7 +319,7 @@ async def get_online_return_policy( 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]]] = (), ) -> online_return_policy.OnlineReturnPolicy: r"""Gets an existing return policy. @@ -332,8 +364,10 @@ async def sample_get_online_return_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: google.shopping.merchant_accounts_v1beta.types.OnlineReturnPolicy: @@ -397,7 +431,7 @@ async def list_online_return_policies( 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.ListOnlineReturnPoliciesAsyncPager: r"""Lists all existing return policies. @@ -442,8 +476,10 @@ async def sample_list_online_return_policies(): 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.shopping.merchant_accounts_v1beta.services.online_return_policy_service.pagers.ListOnlineReturnPoliciesAsyncPager: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/client.py index 9bf18f7a1713..893b5fcc9a31 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.shopping.merchant_accounts_v1beta.services.online_return_policy_service import ( pagers, ) @@ -592,6 +602,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( @@ -658,6 +672,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.shopping.merchant.accounts_v1beta.OnlineReturnPolicyServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.OnlineReturnPolicyService", + "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.shopping.merchant.accounts.v1beta.OnlineReturnPolicyService", + "credentialsType": None, + }, + ) + def get_online_return_policy( self, request: Optional[ @@ -667,7 +704,7 @@ def get_online_return_policy( 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]]] = (), ) -> online_return_policy.OnlineReturnPolicy: r"""Gets an existing return policy. @@ -712,8 +749,10 @@ def sample_get_online_return_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: google.shopping.merchant_accounts_v1beta.types.OnlineReturnPolicy: @@ -774,7 +813,7 @@ def list_online_return_policies( 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.ListOnlineReturnPoliciesPager: r"""Lists all existing return policies. @@ -819,8 +858,10 @@ def sample_list_online_return_policies(): 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.shopping.merchant_accounts_v1beta.services.online_return_policy_service.pagers.ListOnlineReturnPoliciesPager: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/pagers.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/pagers.py index f52f0dba5a7c..455c80d91408 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/pagers.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/pagers.py @@ -67,7 +67,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. @@ -81,8 +81,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 = online_return_policy.ListOnlineReturnPoliciesRequest(request) @@ -143,7 +145,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. @@ -157,8 +159,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 = online_return_policy.ListOnlineReturnPoliciesRequest(request) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/grpc.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/grpc.py index a8d881201cc9..204ded1e558c 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/grpc.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -20,12 +23,90 @@ 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.shopping.merchant_accounts_v1beta.types import online_return_policy from .base import DEFAULT_CLIENT_INFO, OnlineReturnPolicyServiceTransport +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.shopping.merchant.accounts.v1beta.OnlineReturnPolicyService", + "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.shopping.merchant.accounts.v1beta.OnlineReturnPolicyService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class OnlineReturnPolicyServiceGrpcTransport(OnlineReturnPolicyServiceTransport): """gRPC backend transport for OnlineReturnPolicyService. @@ -184,7 +265,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 @@ -261,7 +347,7 @@ def get_online_return_policy( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_online_return_policy" not in self._stubs: - self._stubs["get_online_return_policy"] = self.grpc_channel.unary_unary( + self._stubs["get_online_return_policy"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.OnlineReturnPolicyService/GetOnlineReturnPolicy", request_serializer=online_return_policy.GetOnlineReturnPolicyRequest.serialize, response_deserializer=online_return_policy.OnlineReturnPolicy.deserialize, @@ -290,7 +376,9 @@ def list_online_return_policies( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_online_return_policies" not in self._stubs: - self._stubs["list_online_return_policies"] = self.grpc_channel.unary_unary( + self._stubs[ + "list_online_return_policies" + ] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.OnlineReturnPolicyService/ListOnlineReturnPolicies", request_serializer=online_return_policy.ListOnlineReturnPoliciesRequest.serialize, response_deserializer=online_return_policy.ListOnlineReturnPoliciesResponse.deserialize, @@ -298,7 +386,7 @@ def list_online_return_policies( return self._stubs["list_online_return_policies"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/grpc_asyncio.py index 1b0f450584ee..8e811e428e8d 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -22,14 +25,93 @@ 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 from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_accounts_v1beta.types import online_return_policy from .base import DEFAULT_CLIENT_INFO, OnlineReturnPolicyServiceTransport from .grpc import OnlineReturnPolicyServiceGrpcTransport +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.shopping.merchant.accounts.v1beta.OnlineReturnPolicyService", + "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.shopping.merchant.accounts.v1beta.OnlineReturnPolicyService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class OnlineReturnPolicyServiceGrpcAsyncIOTransport(OnlineReturnPolicyServiceTransport): """gRPC AsyncIO backend transport for OnlineReturnPolicyService. @@ -231,10 +313,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 @@ -269,7 +354,7 @@ def get_online_return_policy( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_online_return_policy" not in self._stubs: - self._stubs["get_online_return_policy"] = self.grpc_channel.unary_unary( + self._stubs["get_online_return_policy"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.OnlineReturnPolicyService/GetOnlineReturnPolicy", request_serializer=online_return_policy.GetOnlineReturnPolicyRequest.serialize, response_deserializer=online_return_policy.OnlineReturnPolicy.deserialize, @@ -298,7 +383,9 @@ def list_online_return_policies( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_online_return_policies" not in self._stubs: - self._stubs["list_online_return_policies"] = self.grpc_channel.unary_unary( + self._stubs[ + "list_online_return_policies" + ] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.OnlineReturnPolicyService/ListOnlineReturnPolicies", request_serializer=online_return_policy.ListOnlineReturnPoliciesRequest.serialize, response_deserializer=online_return_policy.ListOnlineReturnPoliciesResponse.deserialize, @@ -326,7 +413,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/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/rest.py index 61874b2f4e85..4efb4dd8e9eb 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -37,6 +37,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, @@ -85,9 +93,10 @@ def post_list_online_return_policies(self, response): def pre_get_online_return_policy( self, request: online_return_policy.GetOnlineReturnPolicyRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - online_return_policy.GetOnlineReturnPolicyRequest, Sequence[Tuple[str, str]] + online_return_policy.GetOnlineReturnPolicyRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for get_online_return_policy @@ -110,9 +119,10 @@ def post_get_online_return_policy( def pre_list_online_return_policies( self, request: online_return_policy.ListOnlineReturnPoliciesRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - online_return_policy.ListOnlineReturnPoliciesRequest, Sequence[Tuple[str, str]] + online_return_policy.ListOnlineReturnPoliciesRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for list_online_return_policies @@ -263,7 +273,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]]] = (), ) -> online_return_policy.OnlineReturnPolicy: r"""Call the get online return policy method over HTTP. @@ -274,8 +284,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: ~.online_return_policy.OnlineReturnPolicy: @@ -289,6 +301,7 @@ def __call__( http_options = ( _BaseOnlineReturnPolicyServiceRestTransport._BaseGetOnlineReturnPolicy._get_http_options() ) + request, metadata = self._interceptor.pre_get_online_return_policy( request, metadata ) @@ -301,6 +314,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.shopping.merchant.accounts_v1beta.OnlineReturnPolicyServiceClient.GetOnlineReturnPolicy", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.OnlineReturnPolicyService", + "rpcName": "GetOnlineReturnPolicy", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = OnlineReturnPolicyServiceRestTransport._GetOnlineReturnPolicy._get_response( self._host, @@ -321,7 +361,31 @@ def __call__( pb_resp = online_return_policy.OnlineReturnPolicy.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_online_return_policy(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = online_return_policy.OnlineReturnPolicy.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.shopping.merchant.accounts_v1beta.OnlineReturnPolicyServiceClient.get_online_return_policy", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.OnlineReturnPolicyService", + "rpcName": "GetOnlineReturnPolicy", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListOnlineReturnPolicies( @@ -361,7 +425,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]]] = (), ) -> online_return_policy.ListOnlineReturnPoliciesResponse: r"""Call the list online return policies method over HTTP. @@ -373,8 +437,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: ~.online_return_policy.ListOnlineReturnPoliciesResponse: @@ -386,6 +452,7 @@ def __call__( http_options = ( _BaseOnlineReturnPolicyServiceRestTransport._BaseListOnlineReturnPolicies._get_http_options() ) + request, metadata = self._interceptor.pre_list_online_return_policies( request, metadata ) @@ -398,6 +465,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.shopping.merchant.accounts_v1beta.OnlineReturnPolicyServiceClient.ListOnlineReturnPolicies", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.OnlineReturnPolicyService", + "rpcName": "ListOnlineReturnPolicies", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = OnlineReturnPolicyServiceRestTransport._ListOnlineReturnPolicies._get_response( self._host, @@ -418,7 +512,33 @@ def __call__( pb_resp = online_return_policy.ListOnlineReturnPoliciesResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_online_return_policies(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + online_return_policy.ListOnlineReturnPoliciesResponse.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.shopping.merchant.accounts_v1beta.OnlineReturnPolicyServiceClient.list_online_return_policies", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.OnlineReturnPolicyService", + "rpcName": "ListOnlineReturnPolicies", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/async_client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/async_client.py index 91f454d23bcc..ca68af8de955 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/async_client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -49,6 +50,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, ProgramsServiceTransport from .transports.grpc_asyncio import ProgramsServiceGrpcAsyncIOTransport +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 ProgramsServiceAsyncClient: """Service for program management. @@ -267,6 +277,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.shopping.merchant.accounts_v1beta.ProgramsServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.ProgramsService", + "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.shopping.merchant.accounts.v1beta.ProgramsService", + "credentialsType": None, + }, + ) + async def get_program( self, request: Optional[Union[programs.GetProgramRequest, dict]] = None, @@ -274,7 +306,7 @@ async def get_program( 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]]] = (), ) -> programs.Program: r"""Retrieves the specified program for the account. @@ -318,8 +350,10 @@ async def sample_get_program(): 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.shopping.merchant_accounts_v1beta.types.Program: @@ -387,7 +421,7 @@ async def list_programs( 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.ListProgramsAsyncPager: r"""Retrieves all programs for the account. @@ -432,8 +466,10 @@ async def sample_list_programs(): 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.shopping.merchant_accounts_v1beta.services.programs_service.pagers.ListProgramsAsyncPager: @@ -508,7 +544,7 @@ async def enable_program( 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]]] = (), ) -> programs.Program: r"""Enable participation in the specified program for the account. Executing this method requires admin access. @@ -554,8 +590,10 @@ async def sample_enable_program(): 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.shopping.merchant_accounts_v1beta.types.Program: @@ -623,7 +661,7 @@ async def disable_program( 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]]] = (), ) -> programs.Program: r"""Disable participation in the specified program for the account. Executing this method requires admin @@ -670,8 +708,10 @@ async def sample_disable_program(): 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.shopping.merchant_accounts_v1beta.types.Program: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/client.py index 5f27afb0e040..d1c7f8a239c2 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.shopping.merchant_accounts_v1beta.services.programs_service import pagers from google.shopping.merchant_accounts_v1beta.types import programs @@ -586,6 +596,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 +665,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.shopping.merchant.accounts_v1beta.ProgramsServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.ProgramsService", + "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.shopping.merchant.accounts.v1beta.ProgramsService", + "credentialsType": None, + }, + ) + def get_program( self, request: Optional[Union[programs.GetProgramRequest, dict]] = None, @@ -658,7 +695,7 @@ def get_program( 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]]] = (), ) -> programs.Program: r"""Retrieves the specified program for the account. @@ -702,8 +739,10 @@ def sample_get_program(): 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.shopping.merchant_accounts_v1beta.types.Program: @@ -768,7 +807,7 @@ def list_programs( 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.ListProgramsPager: r"""Retrieves all programs for the account. @@ -813,8 +852,10 @@ def sample_list_programs(): 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.shopping.merchant_accounts_v1beta.services.programs_service.pagers.ListProgramsPager: @@ -886,7 +927,7 @@ def enable_program( 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]]] = (), ) -> programs.Program: r"""Enable participation in the specified program for the account. Executing this method requires admin access. @@ -932,8 +973,10 @@ def sample_enable_program(): 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.shopping.merchant_accounts_v1beta.types.Program: @@ -998,7 +1041,7 @@ def disable_program( 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]]] = (), ) -> programs.Program: r"""Disable participation in the specified program for the account. Executing this method requires admin @@ -1045,8 +1088,10 @@ def sample_disable_program(): 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.shopping.merchant_accounts_v1beta.types.Program: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/pagers.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/pagers.py index 5c13da592ed3..497ad2f88007 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/pagers.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/pagers.py @@ -67,7 +67,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. @@ -81,8 +81,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 = programs.ListProgramsRequest(request) @@ -141,7 +143,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. @@ -155,8 +157,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 = programs.ListProgramsRequest(request) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/grpc.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/grpc.py index 91b9f3bbdc5f..b060d02a4a3f 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/grpc.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -20,12 +23,90 @@ 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.shopping.merchant_accounts_v1beta.types import programs from .base import DEFAULT_CLIENT_INFO, ProgramsServiceTransport +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.shopping.merchant.accounts.v1beta.ProgramsService", + "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.shopping.merchant.accounts.v1beta.ProgramsService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class ProgramsServiceGrpcTransport(ProgramsServiceTransport): """gRPC backend transport for ProgramsService. @@ -189,7 +270,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 @@ -261,7 +347,7 @@ def get_program(self) -> Callable[[programs.GetProgramRequest], programs.Program # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_program" not in self._stubs: - self._stubs["get_program"] = self.grpc_channel.unary_unary( + self._stubs["get_program"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.ProgramsService/GetProgram", request_serializer=programs.GetProgramRequest.serialize, response_deserializer=programs.Program.deserialize, @@ -287,7 +373,7 @@ def list_programs( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_programs" not in self._stubs: - self._stubs["list_programs"] = self.grpc_channel.unary_unary( + self._stubs["list_programs"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.ProgramsService/ListPrograms", request_serializer=programs.ListProgramsRequest.serialize, response_deserializer=programs.ListProgramsResponse.deserialize, @@ -314,7 +400,7 @@ def enable_program( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "enable_program" not in self._stubs: - self._stubs["enable_program"] = self.grpc_channel.unary_unary( + self._stubs["enable_program"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.ProgramsService/EnableProgram", request_serializer=programs.EnableProgramRequest.serialize, response_deserializer=programs.Program.deserialize, @@ -342,7 +428,7 @@ def disable_program( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "disable_program" not in self._stubs: - self._stubs["disable_program"] = self.grpc_channel.unary_unary( + self._stubs["disable_program"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.ProgramsService/DisableProgram", request_serializer=programs.DisableProgramRequest.serialize, response_deserializer=programs.Program.deserialize, @@ -350,7 +436,7 @@ def disable_program( return self._stubs["disable_program"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/grpc_asyncio.py index aac76bd3629b..96a69767ca4e 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -22,14 +25,93 @@ 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 from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_accounts_v1beta.types import programs from .base import DEFAULT_CLIENT_INFO, ProgramsServiceTransport from .grpc import ProgramsServiceGrpcTransport +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.shopping.merchant.accounts.v1beta.ProgramsService", + "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.shopping.merchant.accounts.v1beta.ProgramsService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class ProgramsServiceGrpcAsyncIOTransport(ProgramsServiceTransport): """gRPC AsyncIO backend transport for ProgramsService. @@ -236,10 +318,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 @@ -271,7 +356,7 @@ def get_program( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_program" not in self._stubs: - self._stubs["get_program"] = self.grpc_channel.unary_unary( + self._stubs["get_program"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.ProgramsService/GetProgram", request_serializer=programs.GetProgramRequest.serialize, response_deserializer=programs.Program.deserialize, @@ -299,7 +384,7 @@ def list_programs( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_programs" not in self._stubs: - self._stubs["list_programs"] = self.grpc_channel.unary_unary( + self._stubs["list_programs"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.ProgramsService/ListPrograms", request_serializer=programs.ListProgramsRequest.serialize, response_deserializer=programs.ListProgramsResponse.deserialize, @@ -326,7 +411,7 @@ def enable_program( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "enable_program" not in self._stubs: - self._stubs["enable_program"] = self.grpc_channel.unary_unary( + self._stubs["enable_program"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.ProgramsService/EnableProgram", request_serializer=programs.EnableProgramRequest.serialize, response_deserializer=programs.Program.deserialize, @@ -354,7 +439,7 @@ def disable_program( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "disable_program" not in self._stubs: - self._stubs["disable_program"] = self.grpc_channel.unary_unary( + self._stubs["disable_program"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.ProgramsService/DisableProgram", request_serializer=programs.DisableProgramRequest.serialize, response_deserializer=programs.Program.deserialize, @@ -392,7 +477,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/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/rest.py index 9b7a57ef5356..58a305791fd0 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -37,6 +37,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, @@ -101,8 +109,8 @@ def post_list_programs(self, response): def pre_disable_program( self, request: programs.DisableProgramRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[programs.DisableProgramRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[programs.DisableProgramRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for disable_program Override in a subclass to manipulate the request or metadata @@ -122,8 +130,8 @@ def post_disable_program(self, response: programs.Program) -> programs.Program: def pre_enable_program( self, request: programs.EnableProgramRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[programs.EnableProgramRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[programs.EnableProgramRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for enable_program Override in a subclass to manipulate the request or metadata @@ -141,8 +149,10 @@ def post_enable_program(self, response: programs.Program) -> programs.Program: return response def pre_get_program( - self, request: programs.GetProgramRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[programs.GetProgramRequest, Sequence[Tuple[str, str]]]: + self, + request: programs.GetProgramRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[programs.GetProgramRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for get_program Override in a subclass to manipulate the request or metadata @@ -160,8 +170,10 @@ def post_get_program(self, response: programs.Program) -> programs.Program: return response def pre_list_programs( - self, request: programs.ListProgramsRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[programs.ListProgramsRequest, Sequence[Tuple[str, str]]]: + self, + request: programs.ListProgramsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[programs.ListProgramsRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for list_programs Override in a subclass to manipulate the request or metadata @@ -312,7 +324,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]]] = (), ) -> programs.Program: r"""Call the disable program method over HTTP. @@ -323,8 +335,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: ~.programs.Program: @@ -343,6 +357,7 @@ def __call__( http_options = ( _BaseProgramsServiceRestTransport._BaseDisableProgram._get_http_options() ) + request, metadata = self._interceptor.pre_disable_program(request, metadata) transcoded_request = _BaseProgramsServiceRestTransport._BaseDisableProgram._get_transcoded_request( http_options, request @@ -357,6 +372,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.shopping.merchant.accounts_v1beta.ProgramsServiceClient.DisableProgram", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.ProgramsService", + "rpcName": "DisableProgram", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ProgramsServiceRestTransport._DisableProgram._get_response( self._host, @@ -378,7 +420,29 @@ def __call__( pb_resp = programs.Program.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_disable_program(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = programs.Program.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.shopping.merchant.accounts_v1beta.ProgramsServiceClient.disable_program", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.ProgramsService", + "rpcName": "DisableProgram", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _EnableProgram( @@ -416,7 +480,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]]] = (), ) -> programs.Program: r"""Call the enable program method over HTTP. @@ -427,8 +491,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: ~.programs.Program: @@ -447,6 +513,7 @@ def __call__( http_options = ( _BaseProgramsServiceRestTransport._BaseEnableProgram._get_http_options() ) + request, metadata = self._interceptor.pre_enable_program(request, metadata) transcoded_request = _BaseProgramsServiceRestTransport._BaseEnableProgram._get_transcoded_request( http_options, request @@ -461,6 +528,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.shopping.merchant.accounts_v1beta.ProgramsServiceClient.EnableProgram", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.ProgramsService", + "rpcName": "EnableProgram", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ProgramsServiceRestTransport._EnableProgram._get_response( self._host, @@ -482,7 +576,29 @@ def __call__( pb_resp = programs.Program.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_enable_program(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = programs.Program.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.shopping.merchant.accounts_v1beta.ProgramsServiceClient.enable_program", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.ProgramsService", + "rpcName": "EnableProgram", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _GetProgram( @@ -519,7 +635,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]]] = (), ) -> programs.Program: r"""Call the get program method over HTTP. @@ -530,8 +646,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: ~.programs.Program: @@ -550,6 +668,7 @@ def __call__( http_options = ( _BaseProgramsServiceRestTransport._BaseGetProgram._get_http_options() ) + request, metadata = self._interceptor.pre_get_program(request, metadata) transcoded_request = _BaseProgramsServiceRestTransport._BaseGetProgram._get_transcoded_request( http_options, request @@ -560,6 +679,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.shopping.merchant.accounts_v1beta.ProgramsServiceClient.GetProgram", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.ProgramsService", + "rpcName": "GetProgram", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ProgramsServiceRestTransport._GetProgram._get_response( self._host, @@ -580,7 +726,29 @@ def __call__( pb_resp = programs.Program.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_program(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = programs.Program.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.shopping.merchant.accounts_v1beta.ProgramsServiceClient.get_program", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.ProgramsService", + "rpcName": "GetProgram", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListPrograms( @@ -617,7 +785,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]]] = (), ) -> programs.ListProgramsResponse: r"""Call the list programs method over HTTP. @@ -628,8 +796,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: ~.programs.ListProgramsResponse: @@ -641,6 +811,7 @@ def __call__( http_options = ( _BaseProgramsServiceRestTransport._BaseListPrograms._get_http_options() ) + request, metadata = self._interceptor.pre_list_programs(request, metadata) transcoded_request = _BaseProgramsServiceRestTransport._BaseListPrograms._get_transcoded_request( http_options, request @@ -651,6 +822,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.shopping.merchant.accounts_v1beta.ProgramsServiceClient.ListPrograms", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.ProgramsService", + "rpcName": "ListPrograms", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ProgramsServiceRestTransport._ListPrograms._get_response( self._host, @@ -671,7 +869,29 @@ def __call__( pb_resp = programs.ListProgramsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_programs(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = programs.ListProgramsResponse.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.shopping.merchant.accounts_v1beta.ProgramsServiceClient.list_programs", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.ProgramsService", + "rpcName": "ListPrograms", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/async_client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/async_client.py index 2ab9b5c1a99b..bb3cef1dc6bd 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/async_client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -52,6 +53,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, RegionsServiceTransport from .transports.grpc_asyncio import RegionsServiceGrpcAsyncIOTransport +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 RegionsServiceAsyncClient: """Manages regions configuration. @@ -264,6 +274,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.shopping.merchant.accounts_v1beta.RegionsServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.RegionsService", + "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.shopping.merchant.accounts.v1beta.RegionsService", + "credentialsType": None, + }, + ) + async def get_region( self, request: Optional[Union[regions.GetRegionRequest, dict]] = None, @@ -271,7 +303,7 @@ async def get_region( 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]]] = (), ) -> regions.Region: r"""Retrieves a region defined in your Merchant Center account. @@ -315,8 +347,10 @@ async def sample_get_region(): 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.shopping.merchant_accounts_v1beta.types.Region: @@ -384,7 +418,7 @@ async def create_region( region_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]]] = (), ) -> regions.Region: r"""Creates a region definition in your Merchant Center account. Executing this method requires admin access. @@ -442,8 +476,10 @@ async def sample_create_region(): 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.shopping.merchant_accounts_v1beta.types.Region: @@ -514,7 +550,7 @@ async def update_region( 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]]] = (), ) -> regions.Region: r"""Updates a region definition in your Merchant Center account. Executing this method requires admin access. @@ -563,8 +599,10 @@ async def sample_update_region(): 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.shopping.merchant_accounts_v1beta.types.Region: @@ -634,7 +672,7 @@ async def delete_region( 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 region definition from your Merchant Center account. Executing this method requires admin access. @@ -675,8 +713,10 @@ async def sample_delete_region(): 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 @@ -728,7 +768,7 @@ async def list_regions( 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.ListRegionsAsyncPager: r"""Lists the regions in your Merchant Center account. @@ -772,8 +812,10 @@ async def sample_list_regions(): 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.shopping.merchant_accounts_v1beta.services.regions_service.pagers.ListRegionsAsyncPager: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/client.py index 82be07aff917..95d239f36e75 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.protobuf import field_mask_pb2 # type: ignore from google.protobuf import wrappers_pb2 # type: ignore @@ -596,6 +606,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( @@ -661,6 +675,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.shopping.merchant.accounts_v1beta.RegionsServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.RegionsService", + "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.shopping.merchant.accounts.v1beta.RegionsService", + "credentialsType": None, + }, + ) + def get_region( self, request: Optional[Union[regions.GetRegionRequest, dict]] = None, @@ -668,7 +705,7 @@ def get_region( 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]]] = (), ) -> regions.Region: r"""Retrieves a region defined in your Merchant Center account. @@ -712,8 +749,10 @@ def sample_get_region(): 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.shopping.merchant_accounts_v1beta.types.Region: @@ -778,7 +817,7 @@ def create_region( region_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]]] = (), ) -> regions.Region: r"""Creates a region definition in your Merchant Center account. Executing this method requires admin access. @@ -836,8 +875,10 @@ def sample_create_region(): 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.shopping.merchant_accounts_v1beta.types.Region: @@ -905,7 +946,7 @@ def update_region( 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]]] = (), ) -> regions.Region: r"""Updates a region definition in your Merchant Center account. Executing this method requires admin access. @@ -954,8 +995,10 @@ def sample_update_region(): 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.shopping.merchant_accounts_v1beta.types.Region: @@ -1022,7 +1065,7 @@ def delete_region( 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 region definition from your Merchant Center account. Executing this method requires admin access. @@ -1063,8 +1106,10 @@ def sample_delete_region(): 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 @@ -1113,7 +1158,7 @@ def list_regions( 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.ListRegionsPager: r"""Lists the regions in your Merchant Center account. @@ -1157,8 +1202,10 @@ def sample_list_regions(): 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.shopping.merchant_accounts_v1beta.services.regions_service.pagers.ListRegionsPager: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/pagers.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/pagers.py index 3128bcdd68da..e9f44fc45b1c 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/pagers.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/pagers.py @@ -67,7 +67,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. @@ -81,8 +81,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 = regions.ListRegionsRequest(request) @@ -141,7 +143,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. @@ -155,8 +157,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 = regions.ListRegionsRequest(request) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/grpc.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/grpc.py index 9f036a11198b..1b96cfdf085f 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/grpc.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -21,12 +24,90 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore +import proto # type: ignore from google.shopping.merchant_accounts_v1beta.types import regions from .base import DEFAULT_CLIENT_INFO, RegionsServiceTransport +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.shopping.merchant.accounts.v1beta.RegionsService", + "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.shopping.merchant.accounts.v1beta.RegionsService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class RegionsServiceGrpcTransport(RegionsServiceTransport): """gRPC backend transport for RegionsService. @@ -184,7 +265,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 @@ -257,7 +343,7 @@ def get_region(self) -> Callable[[regions.GetRegionRequest], regions.Region]: # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_region" not in self._stubs: - self._stubs["get_region"] = self.grpc_channel.unary_unary( + self._stubs["get_region"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.RegionsService/GetRegion", request_serializer=regions.GetRegionRequest.serialize, response_deserializer=regions.Region.deserialize, @@ -282,7 +368,7 @@ def create_region(self) -> Callable[[regions.CreateRegionRequest], regions.Regio # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_region" not in self._stubs: - self._stubs["create_region"] = self.grpc_channel.unary_unary( + self._stubs["create_region"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.RegionsService/CreateRegion", request_serializer=regions.CreateRegionRequest.serialize, response_deserializer=regions.Region.deserialize, @@ -307,7 +393,7 @@ def update_region(self) -> Callable[[regions.UpdateRegionRequest], regions.Regio # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_region" not in self._stubs: - self._stubs["update_region"] = self.grpc_channel.unary_unary( + self._stubs["update_region"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.RegionsService/UpdateRegion", request_serializer=regions.UpdateRegionRequest.serialize, response_deserializer=regions.Region.deserialize, @@ -332,7 +418,7 @@ def delete_region(self) -> Callable[[regions.DeleteRegionRequest], empty_pb2.Emp # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_region" not in self._stubs: - self._stubs["delete_region"] = self.grpc_channel.unary_unary( + self._stubs["delete_region"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.RegionsService/DeleteRegion", request_serializer=regions.DeleteRegionRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -358,7 +444,7 @@ def list_regions( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_regions" not in self._stubs: - self._stubs["list_regions"] = self.grpc_channel.unary_unary( + self._stubs["list_regions"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.RegionsService/ListRegions", request_serializer=regions.ListRegionsRequest.serialize, response_deserializer=regions.ListRegionsResponse.deserialize, @@ -366,7 +452,7 @@ def list_regions( return self._stubs["list_regions"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/grpc_asyncio.py index 630ee6332d7e..7818c26ac4d4 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -23,14 +26,93 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_accounts_v1beta.types import regions from .base import DEFAULT_CLIENT_INFO, RegionsServiceTransport from .grpc import RegionsServiceGrpcTransport +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.shopping.merchant.accounts.v1beta.RegionsService", + "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.shopping.merchant.accounts.v1beta.RegionsService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class RegionsServiceGrpcAsyncIOTransport(RegionsServiceTransport): """gRPC AsyncIO backend transport for RegionsService. @@ -231,10 +313,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 @@ -267,7 +352,7 @@ def get_region( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_region" not in self._stubs: - self._stubs["get_region"] = self.grpc_channel.unary_unary( + self._stubs["get_region"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.RegionsService/GetRegion", request_serializer=regions.GetRegionRequest.serialize, response_deserializer=regions.Region.deserialize, @@ -294,7 +379,7 @@ def create_region( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_region" not in self._stubs: - self._stubs["create_region"] = self.grpc_channel.unary_unary( + self._stubs["create_region"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.RegionsService/CreateRegion", request_serializer=regions.CreateRegionRequest.serialize, response_deserializer=regions.Region.deserialize, @@ -321,7 +406,7 @@ def update_region( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_region" not in self._stubs: - self._stubs["update_region"] = self.grpc_channel.unary_unary( + self._stubs["update_region"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.RegionsService/UpdateRegion", request_serializer=regions.UpdateRegionRequest.serialize, response_deserializer=regions.Region.deserialize, @@ -348,7 +433,7 @@ def delete_region( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_region" not in self._stubs: - self._stubs["delete_region"] = self.grpc_channel.unary_unary( + self._stubs["delete_region"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.RegionsService/DeleteRegion", request_serializer=regions.DeleteRegionRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -374,7 +459,7 @@ def list_regions( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_regions" not in self._stubs: - self._stubs["list_regions"] = self.grpc_channel.unary_unary( + self._stubs["list_regions"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.RegionsService/ListRegions", request_serializer=regions.ListRegionsRequest.serialize, response_deserializer=regions.ListRegionsResponse.deserialize, @@ -417,7 +502,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/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/rest.py index a1928d09add4..c232076cad01 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -38,6 +38,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, @@ -104,8 +112,10 @@ def post_update_region(self, response): """ def pre_create_region( - self, request: regions.CreateRegionRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[regions.CreateRegionRequest, Sequence[Tuple[str, str]]]: + self, + request: regions.CreateRegionRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[regions.CreateRegionRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for create_region Override in a subclass to manipulate the request or metadata @@ -123,8 +133,10 @@ def post_create_region(self, response: regions.Region) -> regions.Region: return response def pre_delete_region( - self, request: regions.DeleteRegionRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[regions.DeleteRegionRequest, Sequence[Tuple[str, str]]]: + self, + request: regions.DeleteRegionRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[regions.DeleteRegionRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for delete_region Override in a subclass to manipulate the request or metadata @@ -133,8 +145,10 @@ def pre_delete_region( return request, metadata def pre_get_region( - self, request: regions.GetRegionRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[regions.GetRegionRequest, Sequence[Tuple[str, str]]]: + self, + request: regions.GetRegionRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[regions.GetRegionRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for get_region Override in a subclass to manipulate the request or metadata @@ -152,8 +166,10 @@ def post_get_region(self, response: regions.Region) -> regions.Region: return response def pre_list_regions( - self, request: regions.ListRegionsRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[regions.ListRegionsRequest, Sequence[Tuple[str, str]]]: + self, + request: regions.ListRegionsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[regions.ListRegionsRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for list_regions Override in a subclass to manipulate the request or metadata @@ -173,8 +189,10 @@ def post_list_regions( return response def pre_update_region( - self, request: regions.UpdateRegionRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[regions.UpdateRegionRequest, Sequence[Tuple[str, str]]]: + self, + request: regions.UpdateRegionRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[regions.UpdateRegionRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for update_region Override in a subclass to manipulate the request or metadata @@ -317,7 +335,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]]] = (), ) -> regions.Region: r"""Call the create region method over HTTP. @@ -327,8 +345,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: ~.regions.Region: @@ -346,6 +366,7 @@ def __call__( http_options = ( _BaseRegionsServiceRestTransport._BaseCreateRegion._get_http_options() ) + request, metadata = self._interceptor.pre_create_region(request, metadata) transcoded_request = _BaseRegionsServiceRestTransport._BaseCreateRegion._get_transcoded_request( http_options, request @@ -360,6 +381,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.shopping.merchant.accounts_v1beta.RegionsServiceClient.CreateRegion", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.RegionsService", + "rpcName": "CreateRegion", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = RegionsServiceRestTransport._CreateRegion._get_response( self._host, @@ -381,7 +429,29 @@ def __call__( pb_resp = regions.Region.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_region(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = regions.Region.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.shopping.merchant.accounts_v1beta.RegionsServiceClient.create_region", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.RegionsService", + "rpcName": "CreateRegion", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _DeleteRegion( @@ -418,7 +488,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 region method over HTTP. @@ -428,13 +498,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 = ( _BaseRegionsServiceRestTransport._BaseDeleteRegion._get_http_options() ) + request, metadata = self._interceptor.pre_delete_region(request, metadata) transcoded_request = _BaseRegionsServiceRestTransport._BaseDeleteRegion._get_transcoded_request( http_options, request @@ -445,6 +518,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.shopping.merchant.accounts_v1beta.RegionsServiceClient.DeleteRegion", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.RegionsService", + "rpcName": "DeleteRegion", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = RegionsServiceRestTransport._DeleteRegion._get_response( self._host, @@ -494,7 +594,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]]] = (), ) -> regions.Region: r"""Call the get region method over HTTP. @@ -504,8 +604,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: ~.regions.Region: @@ -523,6 +625,7 @@ def __call__( http_options = ( _BaseRegionsServiceRestTransport._BaseGetRegion._get_http_options() ) + request, metadata = self._interceptor.pre_get_region(request, metadata) transcoded_request = ( _BaseRegionsServiceRestTransport._BaseGetRegion._get_transcoded_request( @@ -537,6 +640,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.shopping.merchant.accounts_v1beta.RegionsServiceClient.GetRegion", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.RegionsService", + "rpcName": "GetRegion", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = RegionsServiceRestTransport._GetRegion._get_response( self._host, @@ -557,7 +687,29 @@ def __call__( pb_resp = regions.Region.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_region(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = regions.Region.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.shopping.merchant.accounts_v1beta.RegionsServiceClient.get_region", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.RegionsService", + "rpcName": "GetRegion", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListRegions( @@ -594,7 +746,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]]] = (), ) -> regions.ListRegionsResponse: r"""Call the list regions method over HTTP. @@ -604,8 +756,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: ~.regions.ListRegionsResponse: @@ -615,6 +769,7 @@ def __call__( http_options = ( _BaseRegionsServiceRestTransport._BaseListRegions._get_http_options() ) + request, metadata = self._interceptor.pre_list_regions(request, metadata) transcoded_request = _BaseRegionsServiceRestTransport._BaseListRegions._get_transcoded_request( http_options, request @@ -625,6 +780,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.shopping.merchant.accounts_v1beta.RegionsServiceClient.ListRegions", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.RegionsService", + "rpcName": "ListRegions", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = RegionsServiceRestTransport._ListRegions._get_response( self._host, @@ -645,7 +827,29 @@ def __call__( pb_resp = regions.ListRegionsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_regions(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = regions.ListRegionsResponse.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.shopping.merchant.accounts_v1beta.RegionsServiceClient.list_regions", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.RegionsService", + "rpcName": "ListRegions", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _UpdateRegion( @@ -683,7 +887,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]]] = (), ) -> regions.Region: r"""Call the update region method over HTTP. @@ -693,8 +897,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: ~.regions.Region: @@ -712,6 +918,7 @@ def __call__( http_options = ( _BaseRegionsServiceRestTransport._BaseUpdateRegion._get_http_options() ) + request, metadata = self._interceptor.pre_update_region(request, metadata) transcoded_request = _BaseRegionsServiceRestTransport._BaseUpdateRegion._get_transcoded_request( http_options, request @@ -726,6 +933,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.shopping.merchant.accounts_v1beta.RegionsServiceClient.UpdateRegion", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.RegionsService", + "rpcName": "UpdateRegion", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = RegionsServiceRestTransport._UpdateRegion._get_response( self._host, @@ -747,7 +981,29 @@ def __call__( pb_resp = regions.Region.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_region(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = regions.Region.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.shopping.merchant.accounts_v1beta.RegionsServiceClient.update_region", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.RegionsService", + "rpcName": "UpdateRegion", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/async_client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/async_client.py index 6565278a30e3..1710d88baf73 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/async_client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -48,6 +49,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, ShippingSettingsServiceTransport from .transports.grpc_asyncio import ShippingSettingsServiceGrpcAsyncIOTransport +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 ShippingSettingsServiceAsyncClient: """Service to get method call shipping setting information per @@ -269,6 +279,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.shopping.merchant.accounts_v1beta.ShippingSettingsServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.ShippingSettingsService", + "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.shopping.merchant.accounts.v1beta.ShippingSettingsService", + "credentialsType": None, + }, + ) + async def get_shipping_settings( self, request: Optional[ @@ -278,7 +310,7 @@ async def get_shipping_settings( 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]]] = (), ) -> shippingsettings.ShippingSettings: r"""Retrieve shipping setting information. @@ -321,8 +353,10 @@ async def sample_get_shipping_settings(): 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.shopping.merchant_accounts_v1beta.types.ShippingSettings: @@ -384,7 +418,7 @@ async def insert_shipping_settings( *, 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]]] = (), ) -> shippingsettings.ShippingSettings: r"""Replace the shipping setting of a merchant with the request shipping setting. Executing this method requires @@ -427,8 +461,10 @@ async def sample_insert_shipping_settings(): 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.shopping.merchant_accounts_v1beta.types.ShippingSettings: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/client.py index 56db58577783..cbb279ef081c 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.shopping.merchant_accounts_v1beta.types import shippingsettings from .transports.base import DEFAULT_CLIENT_INFO, ShippingSettingsServiceTransport @@ -580,6 +590,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( @@ -646,6 +660,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.shopping.merchant.accounts_v1beta.ShippingSettingsServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.ShippingSettingsService", + "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.shopping.merchant.accounts.v1beta.ShippingSettingsService", + "credentialsType": None, + }, + ) + def get_shipping_settings( self, request: Optional[ @@ -655,7 +692,7 @@ def get_shipping_settings( 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]]] = (), ) -> shippingsettings.ShippingSettings: r"""Retrieve shipping setting information. @@ -698,8 +735,10 @@ def sample_get_shipping_settings(): 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.shopping.merchant_accounts_v1beta.types.ShippingSettings: @@ -758,7 +797,7 @@ def insert_shipping_settings( *, 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]]] = (), ) -> shippingsettings.ShippingSettings: r"""Replace the shipping setting of a merchant with the request shipping setting. Executing this method requires @@ -801,8 +840,10 @@ def sample_insert_shipping_settings(): 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.shopping.merchant_accounts_v1beta.types.ShippingSettings: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/grpc.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/grpc.py index 83842f03e326..03cb57db04c5 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/grpc.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -20,12 +23,90 @@ 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.shopping.merchant_accounts_v1beta.types import shippingsettings from .base import DEFAULT_CLIENT_INFO, ShippingSettingsServiceTransport +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.shopping.merchant.accounts.v1beta.ShippingSettingsService", + "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.shopping.merchant.accounts.v1beta.ShippingSettingsService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class ShippingSettingsServiceGrpcTransport(ShippingSettingsServiceTransport): """gRPC backend transport for ShippingSettingsService. @@ -180,7 +261,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 @@ -256,7 +342,7 @@ def get_shipping_settings( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_shipping_settings" not in self._stubs: - self._stubs["get_shipping_settings"] = self.grpc_channel.unary_unary( + self._stubs["get_shipping_settings"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.ShippingSettingsService/GetShippingSettings", request_serializer=shippingsettings.GetShippingSettingsRequest.serialize, response_deserializer=shippingsettings.ShippingSettings.deserialize, @@ -287,7 +373,7 @@ def insert_shipping_settings( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "insert_shipping_settings" not in self._stubs: - self._stubs["insert_shipping_settings"] = self.grpc_channel.unary_unary( + self._stubs["insert_shipping_settings"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.ShippingSettingsService/InsertShippingSettings", request_serializer=shippingsettings.InsertShippingSettingsRequest.serialize, response_deserializer=shippingsettings.ShippingSettings.deserialize, @@ -295,7 +381,7 @@ def insert_shipping_settings( return self._stubs["insert_shipping_settings"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/grpc_asyncio.py index 4afad31922bf..c250682ab226 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -22,14 +25,93 @@ 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 from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_accounts_v1beta.types import shippingsettings from .base import DEFAULT_CLIENT_INFO, ShippingSettingsServiceTransport from .grpc import ShippingSettingsServiceGrpcTransport +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.shopping.merchant.accounts.v1beta.ShippingSettingsService", + "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.shopping.merchant.accounts.v1beta.ShippingSettingsService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class ShippingSettingsServiceGrpcAsyncIOTransport(ShippingSettingsServiceTransport): """gRPC AsyncIO backend transport for ShippingSettingsService. @@ -227,10 +309,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 @@ -265,7 +350,7 @@ def get_shipping_settings( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_shipping_settings" not in self._stubs: - self._stubs["get_shipping_settings"] = self.grpc_channel.unary_unary( + self._stubs["get_shipping_settings"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.ShippingSettingsService/GetShippingSettings", request_serializer=shippingsettings.GetShippingSettingsRequest.serialize, response_deserializer=shippingsettings.ShippingSettings.deserialize, @@ -296,7 +381,7 @@ def insert_shipping_settings( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "insert_shipping_settings" not in self._stubs: - self._stubs["insert_shipping_settings"] = self.grpc_channel.unary_unary( + self._stubs["insert_shipping_settings"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.ShippingSettingsService/InsertShippingSettings", request_serializer=shippingsettings.InsertShippingSettingsRequest.serialize, response_deserializer=shippingsettings.ShippingSettings.deserialize, @@ -324,7 +409,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/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/rest.py index 693d3bad2b85..da6b482e5420 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -37,6 +37,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, @@ -85,8 +93,11 @@ def post_insert_shipping_settings(self, response): def pre_get_shipping_settings( self, request: shippingsettings.GetShippingSettingsRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[shippingsettings.GetShippingSettingsRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + shippingsettings.GetShippingSettingsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: """Pre-rpc interceptor for get_shipping_settings Override in a subclass to manipulate the request or metadata @@ -108,9 +119,10 @@ def post_get_shipping_settings( def pre_insert_shipping_settings( self, request: shippingsettings.InsertShippingSettingsRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - shippingsettings.InsertShippingSettingsRequest, Sequence[Tuple[str, str]] + shippingsettings.InsertShippingSettingsRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for insert_shipping_settings @@ -253,7 +265,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]]] = (), ) -> shippingsettings.ShippingSettings: r"""Call the get shipping settings method over HTTP. @@ -263,8 +275,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: ~.shippingsettings.ShippingSettings: @@ -276,6 +290,7 @@ def __call__( http_options = ( _BaseShippingSettingsServiceRestTransport._BaseGetShippingSettings._get_http_options() ) + request, metadata = self._interceptor.pre_get_shipping_settings( request, metadata ) @@ -288,6 +303,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.shopping.merchant.accounts_v1beta.ShippingSettingsServiceClient.GetShippingSettings", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.ShippingSettingsService", + "rpcName": "GetShippingSettings", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ( ShippingSettingsServiceRestTransport._GetShippingSettings._get_response( @@ -310,7 +352,31 @@ def __call__( pb_resp = shippingsettings.ShippingSettings.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_shipping_settings(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = shippingsettings.ShippingSettings.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.shopping.merchant.accounts_v1beta.ShippingSettingsServiceClient.get_shipping_settings", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.ShippingSettingsService", + "rpcName": "GetShippingSettings", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _InsertShippingSettings( @@ -349,7 +415,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]]] = (), ) -> shippingsettings.ShippingSettings: r"""Call the insert shipping settings method over HTTP. @@ -360,8 +426,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: ~.shippingsettings.ShippingSettings: @@ -373,6 +441,7 @@ def __call__( http_options = ( _BaseShippingSettingsServiceRestTransport._BaseInsertShippingSettings._get_http_options() ) + request, metadata = self._interceptor.pre_insert_shipping_settings( request, metadata ) @@ -389,6 +458,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.shopping.merchant.accounts_v1beta.ShippingSettingsServiceClient.InsertShippingSettings", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.ShippingSettingsService", + "rpcName": "InsertShippingSettings", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ShippingSettingsServiceRestTransport._InsertShippingSettings._get_response( self._host, @@ -410,7 +506,31 @@ def __call__( pb_resp = shippingsettings.ShippingSettings.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_insert_shipping_settings(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = shippingsettings.ShippingSettings.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.shopping.merchant.accounts_v1beta.ShippingSettingsServiceClient.insert_shipping_settings", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.ShippingSettingsService", + "rpcName": "InsertShippingSettings", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/async_client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/async_client.py index 128ef18fec98..dd6234ab1da9 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/async_client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -56,6 +57,15 @@ TermsOfServiceAgreementStateServiceGrpcAsyncIOTransport, ) +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 TermsOfServiceAgreementStateServiceAsyncClient: """Service to support ``TermsOfServiceAgreementState`` API.""" @@ -289,6 +299,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.shopping.merchant.accounts_v1beta.TermsOfServiceAgreementStateServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.TermsOfServiceAgreementStateService", + "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.shopping.merchant.accounts.v1beta.TermsOfServiceAgreementStateService", + "credentialsType": None, + }, + ) + async def get_terms_of_service_agreement_state( self, request: Optional[ @@ -301,7 +333,7 @@ async def get_terms_of_service_agreement_state( 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]]] = (), ) -> termsofserviceagreementstate.TermsOfServiceAgreementState: r"""Returns the state of a terms of service agreement. @@ -348,8 +380,10 @@ async def sample_get_terms_of_service_agreement_state(): 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.shopping.merchant_accounts_v1beta.types.TermsOfServiceAgreementState: @@ -446,7 +480,7 @@ async def retrieve_for_application_terms_of_service_agreement_state( 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]]] = (), ) -> termsofserviceagreementstate.TermsOfServiceAgreementState: r"""Retrieves the state of the agreement for the application terms of service. @@ -493,8 +527,10 @@ async def sample_retrieve_for_application_terms_of_service_agreement_state(): 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.shopping.merchant_accounts_v1beta.types.TermsOfServiceAgreementState: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/client.py index 774f9c6d3393..641416abee80 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.shopping.merchant_accounts_v1beta.types import ( termsofserviceagreementstate, termsofservicekind, @@ -629,6 +639,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( @@ -702,6 +716,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.shopping.merchant.accounts_v1beta.TermsOfServiceAgreementStateServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.TermsOfServiceAgreementStateService", + "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.shopping.merchant.accounts.v1beta.TermsOfServiceAgreementStateService", + "credentialsType": None, + }, + ) + def get_terms_of_service_agreement_state( self, request: Optional[ @@ -714,7 +751,7 @@ def get_terms_of_service_agreement_state( 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]]] = (), ) -> termsofserviceagreementstate.TermsOfServiceAgreementState: r"""Returns the state of a terms of service agreement. @@ -761,8 +798,10 @@ def sample_get_terms_of_service_agreement_state(): 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.shopping.merchant_accounts_v1beta.types.TermsOfServiceAgreementState: @@ -858,7 +897,7 @@ def retrieve_for_application_terms_of_service_agreement_state( 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]]] = (), ) -> termsofserviceagreementstate.TermsOfServiceAgreementState: r"""Retrieves the state of the agreement for the application terms of service. @@ -905,8 +944,10 @@ def sample_retrieve_for_application_terms_of_service_agreement_state(): 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.shopping.merchant_accounts_v1beta.types.TermsOfServiceAgreementState: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/grpc.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/grpc.py index f6e88b916fef..557f2da45991 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/grpc.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -20,12 +23,90 @@ 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.shopping.merchant_accounts_v1beta.types import termsofserviceagreementstate from .base import DEFAULT_CLIENT_INFO, TermsOfServiceAgreementStateServiceTransport +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.shopping.merchant.accounts.v1beta.TermsOfServiceAgreementStateService", + "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.shopping.merchant.accounts.v1beta.TermsOfServiceAgreementStateService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class TermsOfServiceAgreementStateServiceGrpcTransport( TermsOfServiceAgreementStateServiceTransport @@ -181,7 +262,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 @@ -261,7 +347,7 @@ def get_terms_of_service_agreement_state( if "get_terms_of_service_agreement_state" not in self._stubs: self._stubs[ "get_terms_of_service_agreement_state" - ] = self.grpc_channel.unary_unary( + ] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.TermsOfServiceAgreementStateService/GetTermsOfServiceAgreementState", request_serializer=termsofserviceagreementstate.GetTermsOfServiceAgreementStateRequest.serialize, response_deserializer=termsofserviceagreementstate.TermsOfServiceAgreementState.deserialize, @@ -299,7 +385,7 @@ def retrieve_for_application_terms_of_service_agreement_state( ): self._stubs[ "retrieve_for_application_terms_of_service_agreement_state" - ] = self.grpc_channel.unary_unary( + ] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.TermsOfServiceAgreementStateService/RetrieveForApplicationTermsOfServiceAgreementState", request_serializer=termsofserviceagreementstate.RetrieveForApplicationTermsOfServiceAgreementStateRequest.serialize, response_deserializer=termsofserviceagreementstate.TermsOfServiceAgreementState.deserialize, @@ -307,7 +393,7 @@ def retrieve_for_application_terms_of_service_agreement_state( return self._stubs["retrieve_for_application_terms_of_service_agreement_state"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/grpc_asyncio.py index 7ed678041e1d..2e0fab7455fc 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -22,14 +25,93 @@ 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 from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_accounts_v1beta.types import termsofserviceagreementstate from .base import DEFAULT_CLIENT_INFO, TermsOfServiceAgreementStateServiceTransport from .grpc import TermsOfServiceAgreementStateServiceGrpcTransport +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.shopping.merchant.accounts.v1beta.TermsOfServiceAgreementStateService", + "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.shopping.merchant.accounts.v1beta.TermsOfServiceAgreementStateService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class TermsOfServiceAgreementStateServiceGrpcAsyncIOTransport( TermsOfServiceAgreementStateServiceTransport @@ -228,10 +310,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 @@ -269,7 +354,7 @@ def get_terms_of_service_agreement_state( if "get_terms_of_service_agreement_state" not in self._stubs: self._stubs[ "get_terms_of_service_agreement_state" - ] = self.grpc_channel.unary_unary( + ] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.TermsOfServiceAgreementStateService/GetTermsOfServiceAgreementState", request_serializer=termsofserviceagreementstate.GetTermsOfServiceAgreementStateRequest.serialize, response_deserializer=termsofserviceagreementstate.TermsOfServiceAgreementState.deserialize, @@ -307,7 +392,7 @@ def retrieve_for_application_terms_of_service_agreement_state( ): self._stubs[ "retrieve_for_application_terms_of_service_agreement_state" - ] = self.grpc_channel.unary_unary( + ] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.TermsOfServiceAgreementStateService/RetrieveForApplicationTermsOfServiceAgreementState", request_serializer=termsofserviceagreementstate.RetrieveForApplicationTermsOfServiceAgreementStateRequest.serialize, response_deserializer=termsofserviceagreementstate.TermsOfServiceAgreementState.deserialize, @@ -335,7 +420,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/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/rest.py index c39b562df96c..d5b957f37f2d 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -37,6 +37,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, @@ -85,10 +93,10 @@ def post_retrieve_for_application_terms_of_service_agreement_state(self, respons def pre_get_terms_of_service_agreement_state( self, request: termsofserviceagreementstate.GetTermsOfServiceAgreementStateRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ termsofserviceagreementstate.GetTermsOfServiceAgreementStateRequest, - Sequence[Tuple[str, str]], + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for get_terms_of_service_agreement_state @@ -111,10 +119,10 @@ def post_get_terms_of_service_agreement_state( def pre_retrieve_for_application_terms_of_service_agreement_state( self, request: termsofserviceagreementstate.RetrieveForApplicationTermsOfServiceAgreementStateRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ termsofserviceagreementstate.RetrieveForApplicationTermsOfServiceAgreementStateRequest, - Sequence[Tuple[str, str]], + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for retrieve_for_application_terms_of_service_agreement_state @@ -264,7 +272,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]]] = (), ) -> termsofserviceagreementstate.TermsOfServiceAgreementState: r"""Call the get terms of service agreement state method over HTTP. @@ -276,8 +284,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: ~.termsofserviceagreementstate.TermsOfServiceAgreementState: @@ -315,6 +325,7 @@ def __call__( http_options = ( _BaseTermsOfServiceAgreementStateServiceRestTransport._BaseGetTermsOfServiceAgreementState._get_http_options() ) + ( request, metadata, @@ -330,6 +341,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.shopping.merchant.accounts_v1beta.TermsOfServiceAgreementStateServiceClient.GetTermsOfServiceAgreementState", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.TermsOfServiceAgreementStateService", + "rpcName": "GetTermsOfServiceAgreementState", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = TermsOfServiceAgreementStateServiceRestTransport._GetTermsOfServiceAgreementState._get_response( self._host, @@ -350,7 +388,31 @@ def __call__( pb_resp = termsofserviceagreementstate.TermsOfServiceAgreementState.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_terms_of_service_agreement_state(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = termsofserviceagreementstate.TermsOfServiceAgreementState.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.shopping.merchant.accounts_v1beta.TermsOfServiceAgreementStateServiceClient.get_terms_of_service_agreement_state", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.TermsOfServiceAgreementStateService", + "rpcName": "GetTermsOfServiceAgreementState", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _RetrieveForApplicationTermsOfServiceAgreementState( @@ -390,7 +452,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]]] = (), ) -> termsofserviceagreementstate.TermsOfServiceAgreementState: r"""Call the retrieve for application terms of service agreement state method over HTTP. @@ -403,8 +465,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: ~.termsofserviceagreementstate.TermsOfServiceAgreementState: @@ -442,6 +506,7 @@ def __call__( http_options = ( _BaseTermsOfServiceAgreementStateServiceRestTransport._BaseRetrieveForApplicationTermsOfServiceAgreementState._get_http_options() ) + ( request, metadata, @@ -457,6 +522,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.shopping.merchant.accounts_v1beta.TermsOfServiceAgreementStateServiceClient.RetrieveForApplicationTermsOfServiceAgreementState", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.TermsOfServiceAgreementStateService", + "rpcName": "RetrieveForApplicationTermsOfServiceAgreementState", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = TermsOfServiceAgreementStateServiceRestTransport._RetrieveForApplicationTermsOfServiceAgreementState._get_response( self._host, @@ -477,9 +569,33 @@ def __call__( pb_resp = termsofserviceagreementstate.TermsOfServiceAgreementState.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_retrieve_for_application_terms_of_service_agreement_state( resp ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = termsofserviceagreementstate.TermsOfServiceAgreementState.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.shopping.merchant.accounts_v1beta.TermsOfServiceAgreementStateServiceClient.retrieve_for_application_terms_of_service_agreement_state", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.TermsOfServiceAgreementStateService", + "rpcName": "RetrieveForApplicationTermsOfServiceAgreementState", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/async_client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/async_client.py index 601dd62bcbee..e0bc803e5d4d 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/async_client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -51,6 +52,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, TermsOfServiceServiceTransport from .transports.grpc_asyncio import TermsOfServiceServiceGrpcAsyncIOTransport +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 TermsOfServiceServiceAsyncClient: """Service to support ``TermsOfService`` API.""" @@ -268,6 +278,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.shopping.merchant.accounts_v1beta.TermsOfServiceServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.TermsOfServiceService", + "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.shopping.merchant.accounts.v1beta.TermsOfServiceService", + "credentialsType": None, + }, + ) + async def get_terms_of_service( self, request: Optional[Union[termsofservice.GetTermsOfServiceRequest, dict]] = None, @@ -275,7 +307,7 @@ async def get_terms_of_service( 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]]] = (), ) -> termsofservice.TermsOfService: r"""Retrieves the ``TermsOfService`` associated with the provided version. @@ -319,8 +351,10 @@ async def sample_get_terms_of_service(): 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.shopping.merchant_accounts_v1beta.types.TermsOfService: @@ -380,7 +414,7 @@ async def retrieve_latest_terms_of_service( *, 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]]] = (), ) -> termsofservice.TermsOfService: r"""Retrieves the latest version of the ``TermsOfService`` for a given ``kind`` and ``region_code``. @@ -419,8 +453,10 @@ async def sample_retrieve_latest_terms_of_service(): 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.shopping.merchant_accounts_v1beta.types.TermsOfService: @@ -461,7 +497,7 @@ async def accept_terms_of_service( 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"""Accepts a ``TermsOfService``. Executing this method requires admin access. @@ -504,8 +540,10 @@ async def sample_accept_terms_of_service(): 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 diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/client.py index 4d7e7c4c3ff1..fb2a75c1f566 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.shopping.merchant_accounts_v1beta.types import ( termsofservice, termsofservicekind, @@ -594,6 +604,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( @@ -660,6 +674,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.shopping.merchant.accounts_v1beta.TermsOfServiceServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.TermsOfServiceService", + "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.shopping.merchant.accounts.v1beta.TermsOfServiceService", + "credentialsType": None, + }, + ) + def get_terms_of_service( self, request: Optional[Union[termsofservice.GetTermsOfServiceRequest, dict]] = None, @@ -667,7 +704,7 @@ def get_terms_of_service( 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]]] = (), ) -> termsofservice.TermsOfService: r"""Retrieves the ``TermsOfService`` associated with the provided version. @@ -711,8 +748,10 @@ def sample_get_terms_of_service(): 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.shopping.merchant_accounts_v1beta.types.TermsOfService: @@ -769,7 +808,7 @@ def retrieve_latest_terms_of_service( *, 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]]] = (), ) -> termsofservice.TermsOfService: r"""Retrieves the latest version of the ``TermsOfService`` for a given ``kind`` and ``region_code``. @@ -808,8 +847,10 @@ def sample_retrieve_latest_terms_of_service(): 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.shopping.merchant_accounts_v1beta.types.TermsOfService: @@ -850,7 +891,7 @@ def accept_terms_of_service( 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"""Accepts a ``TermsOfService``. Executing this method requires admin access. @@ -893,8 +934,10 @@ def sample_accept_terms_of_service(): 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 diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/grpc.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/grpc.py index 06e33647491d..5149dfcb2265 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/grpc.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -21,12 +24,90 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore +import proto # type: ignore from google.shopping.merchant_accounts_v1beta.types import termsofservice from .base import DEFAULT_CLIENT_INFO, TermsOfServiceServiceTransport +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.shopping.merchant.accounts.v1beta.TermsOfServiceService", + "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.shopping.merchant.accounts.v1beta.TermsOfServiceService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class TermsOfServiceServiceGrpcTransport(TermsOfServiceServiceTransport): """gRPC backend transport for TermsOfServiceService. @@ -180,7 +261,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 @@ -257,7 +343,7 @@ def get_terms_of_service( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_terms_of_service" not in self._stubs: - self._stubs["get_terms_of_service"] = self.grpc_channel.unary_unary( + self._stubs["get_terms_of_service"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.TermsOfServiceService/GetTermsOfService", request_serializer=termsofservice.GetTermsOfServiceRequest.serialize, response_deserializer=termsofservice.TermsOfService.deserialize, @@ -290,7 +376,7 @@ def retrieve_latest_terms_of_service( if "retrieve_latest_terms_of_service" not in self._stubs: self._stubs[ "retrieve_latest_terms_of_service" - ] = self.grpc_channel.unary_unary( + ] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.TermsOfServiceService/RetrieveLatestTermsOfService", request_serializer=termsofservice.RetrieveLatestTermsOfServiceRequest.serialize, response_deserializer=termsofservice.TermsOfService.deserialize, @@ -317,7 +403,7 @@ def accept_terms_of_service( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "accept_terms_of_service" not in self._stubs: - self._stubs["accept_terms_of_service"] = self.grpc_channel.unary_unary( + self._stubs["accept_terms_of_service"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.TermsOfServiceService/AcceptTermsOfService", request_serializer=termsofservice.AcceptTermsOfServiceRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -325,7 +411,7 @@ def accept_terms_of_service( return self._stubs["accept_terms_of_service"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/grpc_asyncio.py index ac78365de479..ef269480e268 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -23,14 +26,93 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_accounts_v1beta.types import termsofservice from .base import DEFAULT_CLIENT_INFO, TermsOfServiceServiceTransport from .grpc import TermsOfServiceServiceGrpcTransport +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.shopping.merchant.accounts.v1beta.TermsOfServiceService", + "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.shopping.merchant.accounts.v1beta.TermsOfServiceService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class TermsOfServiceServiceGrpcAsyncIOTransport(TermsOfServiceServiceTransport): """gRPC AsyncIO backend transport for TermsOfServiceService. @@ -227,10 +309,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 @@ -266,7 +351,7 @@ def get_terms_of_service( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_terms_of_service" not in self._stubs: - self._stubs["get_terms_of_service"] = self.grpc_channel.unary_unary( + self._stubs["get_terms_of_service"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.TermsOfServiceService/GetTermsOfService", request_serializer=termsofservice.GetTermsOfServiceRequest.serialize, response_deserializer=termsofservice.TermsOfService.deserialize, @@ -299,7 +384,7 @@ def retrieve_latest_terms_of_service( if "retrieve_latest_terms_of_service" not in self._stubs: self._stubs[ "retrieve_latest_terms_of_service" - ] = self.grpc_channel.unary_unary( + ] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.TermsOfServiceService/RetrieveLatestTermsOfService", request_serializer=termsofservice.RetrieveLatestTermsOfServiceRequest.serialize, response_deserializer=termsofservice.TermsOfService.deserialize, @@ -328,7 +413,7 @@ def accept_terms_of_service( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "accept_terms_of_service" not in self._stubs: - self._stubs["accept_terms_of_service"] = self.grpc_channel.unary_unary( + self._stubs["accept_terms_of_service"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.TermsOfServiceService/AcceptTermsOfService", request_serializer=termsofservice.AcceptTermsOfServiceRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -361,7 +446,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/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/rest.py index ccafb072649b..152800891a4f 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -38,6 +38,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, @@ -90,8 +98,11 @@ def post_retrieve_latest_terms_of_service(self, response): def pre_accept_terms_of_service( self, request: termsofservice.AcceptTermsOfServiceRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[termsofservice.AcceptTermsOfServiceRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + termsofservice.AcceptTermsOfServiceRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: """Pre-rpc interceptor for accept_terms_of_service Override in a subclass to manipulate the request or metadata @@ -102,8 +113,10 @@ def pre_accept_terms_of_service( def pre_get_terms_of_service( self, request: termsofservice.GetTermsOfServiceRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[termsofservice.GetTermsOfServiceRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + termsofservice.GetTermsOfServiceRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for get_terms_of_service Override in a subclass to manipulate the request or metadata @@ -125,9 +138,10 @@ def post_get_terms_of_service( def pre_retrieve_latest_terms_of_service( self, request: termsofservice.RetrieveLatestTermsOfServiceRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - termsofservice.RetrieveLatestTermsOfServiceRequest, Sequence[Tuple[str, str]] + termsofservice.RetrieveLatestTermsOfServiceRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for retrieve_latest_terms_of_service @@ -269,7 +283,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 accept terms of service method over HTTP. @@ -279,13 +293,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 = ( _BaseTermsOfServiceServiceRestTransport._BaseAcceptTermsOfService._get_http_options() ) + request, metadata = self._interceptor.pre_accept_terms_of_service( request, metadata ) @@ -298,6 +315,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.shopping.merchant.accounts_v1beta.TermsOfServiceServiceClient.AcceptTermsOfService", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.TermsOfServiceService", + "rpcName": "AcceptTermsOfService", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ( TermsOfServiceServiceRestTransport._AcceptTermsOfService._get_response( @@ -350,7 +394,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]]] = (), ) -> termsofservice.TermsOfService: r"""Call the get terms of service method over HTTP. @@ -360,8 +404,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: ~.termsofservice.TermsOfService: @@ -371,6 +417,7 @@ def __call__( http_options = ( _BaseTermsOfServiceServiceRestTransport._BaseGetTermsOfService._get_http_options() ) + request, metadata = self._interceptor.pre_get_terms_of_service( request, metadata ) @@ -383,6 +430,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.shopping.merchant.accounts_v1beta.TermsOfServiceServiceClient.GetTermsOfService", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.TermsOfServiceService", + "rpcName": "GetTermsOfService", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ( TermsOfServiceServiceRestTransport._GetTermsOfService._get_response( @@ -405,7 +479,29 @@ def __call__( pb_resp = termsofservice.TermsOfService.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_terms_of_service(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = termsofservice.TermsOfService.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.shopping.merchant.accounts_v1beta.TermsOfServiceServiceClient.get_terms_of_service", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.TermsOfServiceService", + "rpcName": "GetTermsOfService", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _RetrieveLatestTermsOfService( @@ -445,7 +541,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]]] = (), ) -> termsofservice.TermsOfService: r"""Call the retrieve latest terms of service method over HTTP. @@ -457,8 +553,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: ~.termsofservice.TermsOfService: @@ -468,6 +566,7 @@ def __call__( http_options = ( _BaseTermsOfServiceServiceRestTransport._BaseRetrieveLatestTermsOfService._get_http_options() ) + request, metadata = self._interceptor.pre_retrieve_latest_terms_of_service( request, metadata ) @@ -480,6 +579,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.shopping.merchant.accounts_v1beta.TermsOfServiceServiceClient.RetrieveLatestTermsOfService", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.TermsOfServiceService", + "rpcName": "RetrieveLatestTermsOfService", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = TermsOfServiceServiceRestTransport._RetrieveLatestTermsOfService._get_response( self._host, @@ -500,7 +626,29 @@ def __call__( pb_resp = termsofservice.TermsOfService.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_retrieve_latest_terms_of_service(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = termsofservice.TermsOfService.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.shopping.merchant.accounts_v1beta.TermsOfServiceServiceClient.retrieve_latest_terms_of_service", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.TermsOfServiceService", + "rpcName": "RetrieveLatestTermsOfService", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/async_client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/async_client.py index a984dec524c5..033623c2b0ce 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/async_client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -53,6 +54,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, UserServiceTransport from .transports.grpc_asyncio import UserServiceGrpcAsyncIOTransport +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 UserServiceAsyncClient: """Service to support user API.""" @@ -256,6 +266,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.shopping.merchant.accounts_v1beta.UserServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.UserService", + "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.shopping.merchant.accounts.v1beta.UserService", + "credentialsType": None, + }, + ) + async def get_user( self, request: Optional[Union[user.GetUserRequest, dict]] = None, @@ -263,7 +295,7 @@ async def get_user( 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]]] = (), ) -> user.User: r"""Retrieves a Merchant Center account user. @@ -310,8 +342,10 @@ async def sample_get_user(): 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.shopping.merchant_accounts_v1beta.types.User: @@ -371,7 +405,7 @@ async def create_user( user: Optional[gsma_user.User] = 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]]] = (), ) -> gsma_user.User: r"""Creates a Merchant Center account user. Executing this method requires admin access. @@ -421,8 +455,10 @@ async def sample_create_user(): 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.shopping.merchant_accounts_v1beta.types.User: @@ -485,7 +521,7 @@ async def delete_user( 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 Merchant Center account user. Executing this method requires admin access. @@ -530,8 +566,10 @@ async def sample_delete_user(): 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 @@ -584,7 +622,7 @@ async def update_user( 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]]] = (), ) -> gsma_user.User: r"""Updates a Merchant Center account user. Executing this method requires admin access. @@ -636,8 +674,10 @@ async def sample_update_user(): 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.shopping.merchant_accounts_v1beta.types.User: @@ -702,7 +742,7 @@ async def list_users( 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.ListUsersAsyncPager: r"""Lists all users of a Merchant Center account. @@ -746,8 +786,10 @@ async def sample_list_users(): 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.shopping.merchant_accounts_v1beta.services.user_service.pagers.ListUsersAsyncPager: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/client.py index 3c005342b0a1..2a5d86474254 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.protobuf import field_mask_pb2 # type: ignore from google.shopping.merchant_accounts_v1beta.services.user_service import pagers @@ -590,6 +600,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( @@ -652,6 +666,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.shopping.merchant.accounts_v1beta.UserServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.UserService", + "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.shopping.merchant.accounts.v1beta.UserService", + "credentialsType": None, + }, + ) + def get_user( self, request: Optional[Union[user.GetUserRequest, dict]] = None, @@ -659,7 +696,7 @@ def get_user( 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]]] = (), ) -> user.User: r"""Retrieves a Merchant Center account user. @@ -706,8 +743,10 @@ def sample_get_user(): 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.shopping.merchant_accounts_v1beta.types.User: @@ -766,7 +805,7 @@ def create_user( user: Optional[gsma_user.User] = 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]]] = (), ) -> gsma_user.User: r"""Creates a Merchant Center account user. Executing this method requires admin access. @@ -816,8 +855,10 @@ def sample_create_user(): 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.shopping.merchant_accounts_v1beta.types.User: @@ -877,7 +918,7 @@ def delete_user( 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 Merchant Center account user. Executing this method requires admin access. @@ -922,8 +963,10 @@ def sample_delete_user(): 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 @@ -973,7 +1016,7 @@ def update_user( 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]]] = (), ) -> gsma_user.User: r"""Updates a Merchant Center account user. Executing this method requires admin access. @@ -1025,8 +1068,10 @@ def sample_update_user(): 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.shopping.merchant_accounts_v1beta.types.User: @@ -1088,7 +1133,7 @@ def list_users( 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.ListUsersPager: r"""Lists all users of a Merchant Center account. @@ -1132,8 +1177,10 @@ def sample_list_users(): 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.shopping.merchant_accounts_v1beta.services.user_service.pagers.ListUsersPager: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/pagers.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/pagers.py index 61701037173b..f6271e0a4c05 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/pagers.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/pagers.py @@ -67,7 +67,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. @@ -81,8 +81,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 = user.ListUsersRequest(request) @@ -141,7 +143,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. @@ -155,8 +157,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 = user.ListUsersRequest(request) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/grpc.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/grpc.py index 521bc79dcb80..7379dcf1e361 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/grpc.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -21,13 +24,91 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore +import proto # type: ignore from google.shopping.merchant_accounts_v1beta.types import user from google.shopping.merchant_accounts_v1beta.types import user as gsma_user from .base import DEFAULT_CLIENT_INFO, UserServiceTransport +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.shopping.merchant.accounts.v1beta.UserService", + "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.shopping.merchant.accounts.v1beta.UserService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class UserServiceGrpcTransport(UserServiceTransport): """gRPC backend transport for UserService. @@ -181,7 +262,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 @@ -253,7 +339,7 @@ def get_user(self) -> Callable[[user.GetUserRequest], user.User]: # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_user" not in self._stubs: - self._stubs["get_user"] = self.grpc_channel.unary_unary( + self._stubs["get_user"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.UserService/GetUser", request_serializer=user.GetUserRequest.serialize, response_deserializer=user.User.deserialize, @@ -278,7 +364,7 @@ def create_user(self) -> Callable[[gsma_user.CreateUserRequest], gsma_user.User] # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_user" not in self._stubs: - self._stubs["create_user"] = self.grpc_channel.unary_unary( + self._stubs["create_user"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.UserService/CreateUser", request_serializer=gsma_user.CreateUserRequest.serialize, response_deserializer=gsma_user.User.deserialize, @@ -303,7 +389,7 @@ def delete_user(self) -> Callable[[user.DeleteUserRequest], empty_pb2.Empty]: # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_user" not in self._stubs: - self._stubs["delete_user"] = self.grpc_channel.unary_unary( + self._stubs["delete_user"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.UserService/DeleteUser", request_serializer=user.DeleteUserRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -328,7 +414,7 @@ def update_user(self) -> Callable[[gsma_user.UpdateUserRequest], gsma_user.User] # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_user" not in self._stubs: - self._stubs["update_user"] = self.grpc_channel.unary_unary( + self._stubs["update_user"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.UserService/UpdateUser", request_serializer=gsma_user.UpdateUserRequest.serialize, response_deserializer=gsma_user.User.deserialize, @@ -352,7 +438,7 @@ def list_users(self) -> Callable[[user.ListUsersRequest], user.ListUsersResponse # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_users" not in self._stubs: - self._stubs["list_users"] = self.grpc_channel.unary_unary( + self._stubs["list_users"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.UserService/ListUsers", request_serializer=user.ListUsersRequest.serialize, response_deserializer=user.ListUsersResponse.deserialize, @@ -360,7 +446,7 @@ def list_users(self) -> Callable[[user.ListUsersRequest], user.ListUsersResponse return self._stubs["list_users"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/grpc_asyncio.py index a8bc96ed310b..6c21a8d7ac6d 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -23,8 +26,11 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_accounts_v1beta.types import user from google.shopping.merchant_accounts_v1beta.types import user as gsma_user @@ -32,6 +38,82 @@ from .base import DEFAULT_CLIENT_INFO, UserServiceTransport from .grpc import UserServiceGrpcTransport +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.shopping.merchant.accounts.v1beta.UserService", + "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.shopping.merchant.accounts.v1beta.UserService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class UserServiceGrpcAsyncIOTransport(UserServiceTransport): """gRPC AsyncIO backend transport for UserService. @@ -228,10 +310,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 @@ -261,7 +346,7 @@ def get_user(self) -> Callable[[user.GetUserRequest], Awaitable[user.User]]: # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_user" not in self._stubs: - self._stubs["get_user"] = self.grpc_channel.unary_unary( + self._stubs["get_user"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.UserService/GetUser", request_serializer=user.GetUserRequest.serialize, response_deserializer=user.User.deserialize, @@ -288,7 +373,7 @@ def create_user( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_user" not in self._stubs: - self._stubs["create_user"] = self.grpc_channel.unary_unary( + self._stubs["create_user"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.UserService/CreateUser", request_serializer=gsma_user.CreateUserRequest.serialize, response_deserializer=gsma_user.User.deserialize, @@ -315,7 +400,7 @@ def delete_user( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_user" not in self._stubs: - self._stubs["delete_user"] = self.grpc_channel.unary_unary( + self._stubs["delete_user"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.UserService/DeleteUser", request_serializer=user.DeleteUserRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -342,7 +427,7 @@ def update_user( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_user" not in self._stubs: - self._stubs["update_user"] = self.grpc_channel.unary_unary( + self._stubs["update_user"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.UserService/UpdateUser", request_serializer=gsma_user.UpdateUserRequest.serialize, response_deserializer=gsma_user.User.deserialize, @@ -368,7 +453,7 @@ def list_users( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_users" not in self._stubs: - self._stubs["list_users"] = self.grpc_channel.unary_unary( + self._stubs["list_users"] = self._logged_channel.unary_unary( "/google.shopping.merchant.accounts.v1beta.UserService/ListUsers", request_serializer=user.ListUsersRequest.serialize, response_deserializer=user.ListUsersResponse.deserialize, @@ -411,7 +496,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/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/rest.py index ef09abb79ed8..4421b4cf14d2 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -39,6 +39,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, @@ -105,8 +113,10 @@ def post_update_user(self, response): """ def pre_create_user( - self, request: gsma_user.CreateUserRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[gsma_user.CreateUserRequest, Sequence[Tuple[str, str]]]: + self, + request: gsma_user.CreateUserRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gsma_user.CreateUserRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for create_user Override in a subclass to manipulate the request or metadata @@ -124,8 +134,10 @@ def post_create_user(self, response: gsma_user.User) -> gsma_user.User: return response def pre_delete_user( - self, request: user.DeleteUserRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[user.DeleteUserRequest, Sequence[Tuple[str, str]]]: + self, + request: user.DeleteUserRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[user.DeleteUserRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for delete_user Override in a subclass to manipulate the request or metadata @@ -134,8 +146,10 @@ def pre_delete_user( return request, metadata def pre_get_user( - self, request: user.GetUserRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[user.GetUserRequest, Sequence[Tuple[str, str]]]: + self, + request: user.GetUserRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[user.GetUserRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for get_user Override in a subclass to manipulate the request or metadata @@ -153,8 +167,10 @@ def post_get_user(self, response: user.User) -> user.User: return response def pre_list_users( - self, request: user.ListUsersRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[user.ListUsersRequest, Sequence[Tuple[str, str]]]: + self, + request: user.ListUsersRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[user.ListUsersRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for list_users Override in a subclass to manipulate the request or metadata @@ -174,8 +190,10 @@ def post_list_users( return response def pre_update_user( - self, request: gsma_user.UpdateUserRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[gsma_user.UpdateUserRequest, Sequence[Tuple[str, str]]]: + self, + request: gsma_user.UpdateUserRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gsma_user.UpdateUserRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for update_user Override in a subclass to manipulate the request or metadata @@ -314,7 +332,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]]] = (), ) -> gsma_user.User: r"""Call the create user method over HTTP. @@ -324,8 +342,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: ~.gsma_user.User: @@ -337,6 +357,7 @@ def __call__( http_options = ( _BaseUserServiceRestTransport._BaseCreateUser._get_http_options() ) + request, metadata = self._interceptor.pre_create_user(request, metadata) transcoded_request = ( _BaseUserServiceRestTransport._BaseCreateUser._get_transcoded_request( @@ -355,6 +376,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.shopping.merchant.accounts_v1beta.UserServiceClient.CreateUser", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.UserService", + "rpcName": "CreateUser", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = UserServiceRestTransport._CreateUser._get_response( self._host, @@ -376,7 +424,29 @@ def __call__( pb_resp = gsma_user.User.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_user(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = gsma_user.User.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.shopping.merchant.accounts_v1beta.UserServiceClient.create_user", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.UserService", + "rpcName": "CreateUser", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _DeleteUser( @@ -413,7 +483,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 user method over HTTP. @@ -423,13 +493,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 = ( _BaseUserServiceRestTransport._BaseDeleteUser._get_http_options() ) + request, metadata = self._interceptor.pre_delete_user(request, metadata) transcoded_request = ( _BaseUserServiceRestTransport._BaseDeleteUser._get_transcoded_request( @@ -444,6 +517,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.shopping.merchant.accounts_v1beta.UserServiceClient.DeleteUser", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.UserService", + "rpcName": "DeleteUser", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = UserServiceRestTransport._DeleteUser._get_response( self._host, @@ -491,7 +591,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]]] = (), ) -> user.User: r"""Call the get user method over HTTP. @@ -501,8 +601,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: ~.user.User: @@ -514,6 +616,7 @@ def __call__( http_options = ( _BaseUserServiceRestTransport._BaseGetUser._get_http_options() ) + request, metadata = self._interceptor.pre_get_user(request, metadata) transcoded_request = ( _BaseUserServiceRestTransport._BaseGetUser._get_transcoded_request( @@ -528,6 +631,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.shopping.merchant.accounts_v1beta.UserServiceClient.GetUser", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.UserService", + "rpcName": "GetUser", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = UserServiceRestTransport._GetUser._get_response( self._host, @@ -548,7 +678,29 @@ def __call__( pb_resp = user.User.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_user(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = user.User.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.shopping.merchant.accounts_v1beta.UserServiceClient.get_user", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.UserService", + "rpcName": "GetUser", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListUsers(_BaseUserServiceRestTransport._BaseListUsers, UserServiceRestStub): @@ -583,7 +735,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]]] = (), ) -> user.ListUsersResponse: r"""Call the list users method over HTTP. @@ -593,8 +745,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: ~.user.ListUsersResponse: @@ -604,6 +758,7 @@ def __call__( http_options = ( _BaseUserServiceRestTransport._BaseListUsers._get_http_options() ) + request, metadata = self._interceptor.pre_list_users(request, metadata) transcoded_request = ( _BaseUserServiceRestTransport._BaseListUsers._get_transcoded_request( @@ -618,6 +773,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.shopping.merchant.accounts_v1beta.UserServiceClient.ListUsers", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.UserService", + "rpcName": "ListUsers", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = UserServiceRestTransport._ListUsers._get_response( self._host, @@ -638,7 +820,29 @@ def __call__( pb_resp = user.ListUsersResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_users(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = user.ListUsersResponse.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.shopping.merchant.accounts_v1beta.UserServiceClient.list_users", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.UserService", + "rpcName": "ListUsers", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _UpdateUser( @@ -676,7 +880,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]]] = (), ) -> gsma_user.User: r"""Call the update user method over HTTP. @@ -686,8 +890,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: ~.gsma_user.User: @@ -699,6 +905,7 @@ def __call__( http_options = ( _BaseUserServiceRestTransport._BaseUpdateUser._get_http_options() ) + request, metadata = self._interceptor.pre_update_user(request, metadata) transcoded_request = ( _BaseUserServiceRestTransport._BaseUpdateUser._get_transcoded_request( @@ -717,6 +924,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.shopping.merchant.accounts_v1beta.UserServiceClient.UpdateUser", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.UserService", + "rpcName": "UpdateUser", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = UserServiceRestTransport._UpdateUser._get_response( self._host, @@ -738,7 +972,29 @@ def __call__( pb_resp = gsma_user.User.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_user(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = gsma_user.User.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.shopping.merchant.accounts_v1beta.UserServiceClient.update_user", + extra={ + "serviceName": "google.shopping.merchant.accounts.v1beta.UserService", + "rpcName": "UpdateUser", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-accounts/samples/generated_samples/snippet_metadata_google.shopping.merchant.accounts.v1beta.json b/packages/google-shopping-merchant-accounts/samples/generated_samples/snippet_metadata_google.shopping.merchant.accounts.v1beta.json index 1058eee916c7..c736f9d3c831 100644 --- a/packages/google-shopping-merchant-accounts/samples/generated_samples/snippet_metadata_google.shopping.merchant.accounts.v1beta.json +++ b/packages/google-shopping-merchant-accounts/samples/generated_samples/snippet_metadata_google.shopping.merchant.accounts.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-shopping-merchant-accounts", - "version": "0.2.2" + "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.shopping.merchant_accounts_v1beta.services.account_issue_service.pagers.ListAccountIssuesAsyncPager", @@ -127,7 +127,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.services.account_issue_service.pagers.ListAccountIssuesPager", @@ -208,7 +208,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.AccountTax", @@ -288,7 +288,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.AccountTax", @@ -369,7 +369,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.services.account_tax_service.pagers.ListAccountTaxAsyncPager", @@ -449,7 +449,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.services.account_tax_service.pagers.ListAccountTaxPager", @@ -534,7 +534,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.AccountTax", @@ -618,7 +618,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.AccountTax", @@ -695,7 +695,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Account", @@ -771,7 +771,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Account", @@ -852,7 +852,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_account" @@ -929,7 +929,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_account" @@ -1007,7 +1007,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Account", @@ -1087,7 +1087,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Account", @@ -1164,7 +1164,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.services.accounts_service.pagers.ListAccountsAsyncPager", @@ -1240,7 +1240,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.services.accounts_service.pagers.ListAccountsPager", @@ -1321,7 +1321,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.services.accounts_service.pagers.ListSubAccountsAsyncPager", @@ -1401,7 +1401,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.services.accounts_service.pagers.ListSubAccountsPager", @@ -1486,7 +1486,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Account", @@ -1570,7 +1570,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Account", @@ -1651,7 +1651,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.AutofeedSettings", @@ -1731,7 +1731,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.AutofeedSettings", @@ -1816,7 +1816,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.AutofeedSettings", @@ -1900,7 +1900,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.AutofeedSettings", @@ -1981,7 +1981,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.BusinessIdentity", @@ -2061,7 +2061,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.BusinessIdentity", @@ -2146,7 +2146,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.BusinessIdentity", @@ -2230,7 +2230,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.BusinessIdentity", @@ -2311,7 +2311,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.BusinessInfo", @@ -2391,7 +2391,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.BusinessInfo", @@ -2476,7 +2476,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.BusinessInfo", @@ -2560,7 +2560,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.BusinessInfo", @@ -2641,7 +2641,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.EmailPreferences", @@ -2721,7 +2721,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.EmailPreferences", @@ -2806,7 +2806,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.EmailPreferences", @@ -2890,7 +2890,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.EmailPreferences", @@ -2967,7 +2967,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Homepage", @@ -3043,7 +3043,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Homepage", @@ -3124,7 +3124,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Homepage", @@ -3204,7 +3204,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Homepage", @@ -3281,7 +3281,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Homepage", @@ -3357,7 +3357,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Homepage", @@ -3442,7 +3442,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Homepage", @@ -3526,7 +3526,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Homepage", @@ -3607,7 +3607,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.OnlineReturnPolicy", @@ -3687,7 +3687,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.OnlineReturnPolicy", @@ -3768,7 +3768,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.services.online_return_policy_service.pagers.ListOnlineReturnPoliciesAsyncPager", @@ -3848,7 +3848,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.services.online_return_policy_service.pagers.ListOnlineReturnPoliciesPager", @@ -3929,7 +3929,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Program", @@ -4009,7 +4009,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Program", @@ -4090,7 +4090,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Program", @@ -4170,7 +4170,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Program", @@ -4251,7 +4251,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Program", @@ -4331,7 +4331,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Program", @@ -4412,7 +4412,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.services.programs_service.pagers.ListProgramsAsyncPager", @@ -4492,7 +4492,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.services.programs_service.pagers.ListProgramsPager", @@ -4581,7 +4581,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Region", @@ -4669,7 +4669,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Region", @@ -4750,7 +4750,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_region" @@ -4827,7 +4827,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_region" @@ -4905,7 +4905,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Region", @@ -4985,7 +4985,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Region", @@ -5066,7 +5066,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.services.regions_service.pagers.ListRegionsAsyncPager", @@ -5146,7 +5146,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.services.regions_service.pagers.ListRegionsPager", @@ -5231,7 +5231,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Region", @@ -5315,7 +5315,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.Region", @@ -5396,7 +5396,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.ShippingSettings", @@ -5476,7 +5476,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.ShippingSettings", @@ -5553,7 +5553,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.ShippingSettings", @@ -5629,7 +5629,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.ShippingSettings", @@ -5710,7 +5710,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.TermsOfServiceAgreementState", @@ -5790,7 +5790,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.TermsOfServiceAgreementState", @@ -5871,7 +5871,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.TermsOfServiceAgreementState", @@ -5951,7 +5951,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.TermsOfServiceAgreementState", @@ -6032,7 +6032,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "accept_terms_of_service" @@ -6109,7 +6109,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "accept_terms_of_service" @@ -6187,7 +6187,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.TermsOfService", @@ -6267,7 +6267,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.TermsOfService", @@ -6344,7 +6344,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.TermsOfService", @@ -6420,7 +6420,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.TermsOfService", @@ -6505,7 +6505,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.User", @@ -6589,7 +6589,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.User", @@ -6670,7 +6670,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_user" @@ -6747,7 +6747,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_user" @@ -6825,7 +6825,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.User", @@ -6905,7 +6905,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.User", @@ -6986,7 +6986,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.services.user_service.pagers.ListUsersAsyncPager", @@ -7066,7 +7066,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.services.user_service.pagers.ListUsersPager", @@ -7151,7 +7151,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.User", @@ -7235,7 +7235,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_accounts_v1beta.types.User", diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_account_issue_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_account_issue_service.py index ce8b8b27c933..f55fae63fdf7 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_account_issue_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_account_issue_service.py @@ -1784,6 +1784,7 @@ def test_list_account_issues_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_account_issues(request) @@ -1839,6 +1840,7 @@ def test_list_account_issues_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_account_issues(**mock_args) @@ -2130,6 +2132,7 @@ def test_list_account_issues_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_account_issues(request) @@ -2165,6 +2168,7 @@ def test_list_account_issues_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_account_issues(request) # Establish that the response is the type that we expect. @@ -2205,6 +2209,7 @@ def test_list_account_issues_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 = accountissue.ListAccountIssuesResponse.to_json( accountissue.ListAccountIssuesResponse() ) diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_account_tax_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_account_tax_service.py index 6e5d6b24a423..e219d7f3360f 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_account_tax_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_account_tax_service.py @@ -2407,6 +2407,7 @@ def test_get_account_tax_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_account_tax(request) @@ -2452,6 +2453,7 @@ def test_get_account_tax_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_account_tax(**mock_args) @@ -2592,6 +2594,7 @@ def test_list_account_tax_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_account_tax(request) @@ -2645,6 +2648,7 @@ def test_list_account_tax_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_account_tax(**mock_args) @@ -2841,6 +2845,7 @@ def test_update_account_tax_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_account_tax(request) @@ -2889,6 +2894,7 @@ def test_update_account_tax_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_account_tax(**mock_args) @@ -3217,6 +3223,7 @@ def test_get_account_tax_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.get_account_tax(request) @@ -3253,6 +3260,7 @@ def test_get_account_tax_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_account_tax(request) # Establish that the response is the type that we expect. @@ -3294,6 +3302,7 @@ def test_get_account_tax_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 = account_tax.AccountTax.to_json(account_tax.AccountTax()) req.return_value.content = return_value @@ -3338,6 +3347,7 @@ def test_list_account_tax_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_account_tax(request) @@ -3373,6 +3383,7 @@ def test_list_account_tax_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_account_tax(request) # Establish that the response is the type that we expect. @@ -3413,6 +3424,7 @@ def test_list_account_tax_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 = account_tax.ListAccountTaxResponse.to_json( account_tax.ListAccountTaxResponse() ) @@ -3459,6 +3471,7 @@ def test_update_account_tax_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_account_tax(request) @@ -3580,6 +3593,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.update_account_tax(request) # Establish that the response is the type that we expect. @@ -3621,6 +3635,7 @@ def test_update_account_tax_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 = gsma_account_tax.AccountTax.to_json( gsma_account_tax.AccountTax() ) diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_accounts_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_accounts_service.py index 951b0f3990c6..672309d4d693 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_accounts_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_accounts_service.py @@ -3310,6 +3310,7 @@ def test_get_account_rest_required_fields(request_type=accounts.GetAccountReques 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_account(request) @@ -3355,6 +3356,7 @@ def test_get_account_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_account(**mock_args) @@ -3485,6 +3487,7 @@ def test_create_and_configure_account_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_and_configure_account(request) @@ -3611,6 +3614,7 @@ def test_delete_account_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_account(request) @@ -3654,6 +3658,7 @@ def test_delete_account_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_account(**mock_args) @@ -3781,6 +3786,7 @@ def test_update_account_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_account(request) @@ -3835,6 +3841,7 @@ def test_update_account_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_account(**mock_args) @@ -4072,6 +4079,7 @@ def test_list_sub_accounts_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_sub_accounts(request) @@ -4125,6 +4133,7 @@ def test_list_sub_accounts_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_sub_accounts(**mock_args) @@ -4668,6 +4677,7 @@ def test_get_account_rest_bad_request(request_type=accounts.GetAccountRequest): 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_account(request) @@ -4708,6 +4718,7 @@ def test_get_account_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_account(request) # Establish that the response is the type that we expect. @@ -4751,6 +4762,7 @@ def test_get_account_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 = accounts.Account.to_json(accounts.Account()) req.return_value.content = return_value @@ -4795,6 +4807,7 @@ def test_create_and_configure_account_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.create_and_configure_account(request) @@ -4835,6 +4848,7 @@ def test_create_and_configure_account_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_and_configure_account(request) # Establish that the response is the type that we expect. @@ -4880,6 +4894,7 @@ def test_create_and_configure_account_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 = accounts.Account.to_json(accounts.Account()) req.return_value.content = return_value @@ -4922,6 +4937,7 @@ def test_delete_account_rest_bad_request(request_type=accounts.DeleteAccountRequ 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_account(request) @@ -4952,6 +4968,7 @@ def test_delete_account_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_account(request) # Establish that the response is the type that we expect. @@ -4986,6 +5003,7 @@ def test_delete_account_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 = accounts.DeleteAccountRequest() metadata = [ @@ -5024,6 +5042,7 @@ def test_update_account_rest_bad_request(request_type=accounts.UpdateAccountRequ 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_account(request) @@ -5140,6 +5159,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.update_account(request) # Establish that the response is the type that we expect. @@ -5183,6 +5203,7 @@ def test_update_account_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 = accounts.Account.to_json(accounts.Account()) req.return_value.content = return_value @@ -5225,6 +5246,7 @@ def test_list_accounts_rest_bad_request(request_type=accounts.ListAccountsReques 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_accounts(request) @@ -5260,6 +5282,7 @@ def test_list_accounts_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_accounts(request) # Establish that the response is the type that we expect. @@ -5298,6 +5321,7 @@ def test_list_accounts_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 = accounts.ListAccountsResponse.to_json( accounts.ListAccountsResponse() ) @@ -5344,6 +5368,7 @@ def test_list_sub_accounts_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_sub_accounts(request) @@ -5379,6 +5404,7 @@ def test_list_sub_accounts_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_sub_accounts(request) # Establish that the response is the type that we expect. @@ -5419,6 +5445,7 @@ def test_list_sub_accounts_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 = accounts.ListSubAccountsResponse.to_json( accounts.ListSubAccountsResponse() ) diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_autofeed_settings_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_autofeed_settings_service.py index 32f10460d82a..27f14e47def8 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_autofeed_settings_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_autofeed_settings_service.py @@ -1939,6 +1939,7 @@ def test_get_autofeed_settings_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_autofeed_settings(request) @@ -1984,6 +1985,7 @@ def test_get_autofeed_settings_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_autofeed_settings(**mock_args) @@ -2118,6 +2120,7 @@ def test_update_autofeed_settings_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_autofeed_settings(request) @@ -2174,6 +2177,7 @@ def test_update_autofeed_settings_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_autofeed_settings(**mock_args) @@ -2460,6 +2464,7 @@ def test_get_autofeed_settings_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.get_autofeed_settings(request) @@ -2497,6 +2502,7 @@ def test_get_autofeed_settings_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_autofeed_settings(request) # Establish that the response is the type that we expect. @@ -2539,6 +2545,7 @@ def test_get_autofeed_settings_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 = autofeedsettings.AutofeedSettings.to_json( autofeedsettings.AutofeedSettings() ) @@ -2585,6 +2592,7 @@ def test_update_autofeed_settings_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_autofeed_settings(request) @@ -2696,6 +2704,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.update_autofeed_settings(request) # Establish that the response is the type that we expect. @@ -2740,6 +2749,7 @@ def test_update_autofeed_settings_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 = autofeedsettings.AutofeedSettings.to_json( autofeedsettings.AutofeedSettings() ) diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_business_identity_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_business_identity_service.py index 34652d14ca8b..fda9d2bbbf68 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_business_identity_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_business_identity_service.py @@ -1943,6 +1943,7 @@ def test_get_business_identity_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_business_identity(request) @@ -1988,6 +1989,7 @@ def test_get_business_identity_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_business_identity(**mock_args) @@ -2122,6 +2124,7 @@ def test_update_business_identity_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_business_identity(request) @@ -2178,6 +2181,7 @@ def test_update_business_identity_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_business_identity(**mock_args) @@ -2462,6 +2466,7 @@ def test_get_business_identity_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.get_business_identity(request) @@ -2498,6 +2503,7 @@ def test_get_business_identity_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_business_identity(request) # Establish that the response is the type that we expect. @@ -2542,6 +2548,7 @@ def test_get_business_identity_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 = businessidentity.BusinessIdentity.to_json( businessidentity.BusinessIdentity() ) @@ -2588,6 +2595,7 @@ def test_update_business_identity_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_business_identity(request) @@ -2702,6 +2710,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.update_business_identity(request) # Establish that the response is the type that we expect. @@ -2748,6 +2757,7 @@ def test_update_business_identity_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 = businessidentity.BusinessIdentity.to_json( businessidentity.BusinessIdentity() ) diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_business_info_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_business_info_service.py index fe9a65356193..55f233b43794 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_business_info_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_business_info_service.py @@ -1956,6 +1956,7 @@ def test_get_business_info_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_business_info(request) @@ -2001,6 +2002,7 @@ def test_get_business_info_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_business_info(**mock_args) @@ -2134,6 +2136,7 @@ def test_update_business_info_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_business_info(request) @@ -2188,6 +2191,7 @@ def test_update_business_info_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_business_info(**mock_args) @@ -2474,6 +2478,7 @@ def test_get_business_info_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.get_business_info(request) @@ -2511,6 +2516,7 @@ def test_get_business_info_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_business_info(request) # Establish that the response is the type that we expect. @@ -2559,6 +2565,7 @@ def test_get_business_info_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 = businessinfo.BusinessInfo.to_json(businessinfo.BusinessInfo()) req.return_value.content = return_value @@ -2603,6 +2610,7 @@ def test_update_business_info_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_business_info(request) @@ -2734,6 +2742,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.update_business_info(request) # Establish that the response is the type that we expect. @@ -2782,6 +2791,7 @@ def test_update_business_info_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 = businessinfo.BusinessInfo.to_json(businessinfo.BusinessInfo()) req.return_value.content = return_value diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_email_preferences_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_email_preferences_service.py index 78d13efce5b5..aa20e576c90a 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_email_preferences_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_email_preferences_service.py @@ -1939,6 +1939,7 @@ def test_get_email_preferences_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_email_preferences(request) @@ -1984,6 +1985,7 @@ def test_get_email_preferences_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_email_preferences(**mock_args) @@ -2118,6 +2120,7 @@ def test_update_email_preferences_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_email_preferences(request) @@ -2176,6 +2179,7 @@ def test_update_email_preferences_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_email_preferences(**mock_args) @@ -2460,6 +2464,7 @@ def test_get_email_preferences_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.get_email_preferences(request) @@ -2496,6 +2501,7 @@ def test_get_email_preferences_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_email_preferences(request) # Establish that the response is the type that we expect. @@ -2539,6 +2545,7 @@ def test_get_email_preferences_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 = emailpreferences.EmailPreferences.to_json( emailpreferences.EmailPreferences() ) @@ -2587,6 +2594,7 @@ def test_update_email_preferences_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_email_preferences(request) @@ -2698,6 +2706,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.update_email_preferences(request) # Establish that the response is the type that we expect. @@ -2743,6 +2752,7 @@ def test_update_email_preferences_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 = emailpreferences.EmailPreferences.to_json( emailpreferences.EmailPreferences() ) diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_homepage_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_homepage_service.py index 35711df444ea..3c1c890a3c77 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_homepage_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_homepage_service.py @@ -2345,6 +2345,7 @@ def test_get_homepage_rest_required_fields(request_type=homepage.GetHomepageRequ 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_homepage(request) @@ -2390,6 +2391,7 @@ def test_get_homepage_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_homepage(**mock_args) @@ -2518,6 +2520,7 @@ def test_update_homepage_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_homepage(request) @@ -2572,6 +2575,7 @@ def test_update_homepage_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_homepage(**mock_args) @@ -2705,6 +2709,7 @@ def test_claim_homepage_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.claim_homepage(request) @@ -2827,6 +2832,7 @@ def test_unclaim_homepage_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.unclaim_homepage(request) @@ -3190,6 +3196,7 @@ def test_get_homepage_rest_bad_request(request_type=homepage.GetHomepageRequest) 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_homepage(request) @@ -3227,6 +3234,7 @@ def test_get_homepage_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_homepage(request) # Establish that the response is the type that we expect. @@ -3267,6 +3275,7 @@ def test_get_homepage_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 = homepage.Homepage.to_json(homepage.Homepage()) req.return_value.content = return_value @@ -3311,6 +3320,7 @@ def test_update_homepage_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_homepage(request) @@ -3420,6 +3430,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.update_homepage(request) # Establish that the response is the type that we expect. @@ -3462,6 +3473,7 @@ def test_update_homepage_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 = gsma_homepage.Homepage.to_json(gsma_homepage.Homepage()) req.return_value.content = return_value @@ -3504,6 +3516,7 @@ def test_claim_homepage_rest_bad_request(request_type=homepage.ClaimHomepageRequ 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.claim_homepage(request) @@ -3541,6 +3554,7 @@ def test_claim_homepage_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.claim_homepage(request) # Establish that the response is the type that we expect. @@ -3581,6 +3595,7 @@ def test_claim_homepage_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 = homepage.Homepage.to_json(homepage.Homepage()) req.return_value.content = return_value @@ -3625,6 +3640,7 @@ def test_unclaim_homepage_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.unclaim_homepage(request) @@ -3662,6 +3678,7 @@ def test_unclaim_homepage_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.unclaim_homepage(request) # Establish that the response is the type that we expect. @@ -3704,6 +3721,7 @@ def test_unclaim_homepage_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 = homepage.Homepage.to_json(homepage.Homepage()) req.return_value.content = return_value diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_online_return_policy_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_online_return_policy_service.py index 82c9f209acbf..2f65f8b7cb60 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_online_return_policy_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_online_return_policy_service.py @@ -2189,6 +2189,7 @@ def test_get_online_return_policy_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_online_return_policy(request) @@ -2234,6 +2235,7 @@ def test_get_online_return_policy_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_online_return_policy(**mock_args) @@ -2379,6 +2381,7 @@ def test_list_online_return_policies_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_online_return_policies(request) @@ -2434,6 +2437,7 @@ def test_list_online_return_policies_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_online_return_policies(**mock_args) @@ -2794,6 +2798,7 @@ def test_get_online_return_policy_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.get_online_return_policy(request) @@ -2840,6 +2845,7 @@ def test_get_online_return_policy_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_online_return_policy(request) # Establish that the response is the type that we expect. @@ -2895,6 +2901,7 @@ def test_get_online_return_policy_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 = online_return_policy.OnlineReturnPolicy.to_json( online_return_policy.OnlineReturnPolicy() ) @@ -2941,6 +2948,7 @@ def test_list_online_return_policies_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_online_return_policies(request) @@ -2978,6 +2986,7 @@ def test_list_online_return_policies_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_online_return_policies(request) # Establish that the response is the type that we expect. @@ -3020,6 +3029,7 @@ def test_list_online_return_policies_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 = online_return_policy.ListOnlineReturnPoliciesResponse.to_json( online_return_policy.ListOnlineReturnPoliciesResponse() ) diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_programs_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_programs_service.py index 189a56eaaf44..efa73d73a38f 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_programs_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_programs_service.py @@ -2696,6 +2696,7 @@ def test_get_program_rest_required_fields(request_type=programs.GetProgramReques 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_program(request) @@ -2741,6 +2742,7 @@ def test_get_program_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_program(**mock_args) @@ -2876,6 +2878,7 @@ def test_list_programs_rest_required_fields(request_type=programs.ListProgramsRe 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_programs(request) @@ -2929,6 +2932,7 @@ def test_list_programs_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_programs(**mock_args) @@ -3121,6 +3125,7 @@ def test_enable_program_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.enable_program(request) @@ -3166,6 +3171,7 @@ def test_enable_program_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.enable_program(**mock_args) @@ -3298,6 +3304,7 @@ def test_disable_program_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.disable_program(request) @@ -3343,6 +3350,7 @@ def test_disable_program_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.disable_program(**mock_args) @@ -3719,6 +3727,7 @@ def test_get_program_rest_bad_request(request_type=programs.GetProgramRequest): 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_program(request) @@ -3757,6 +3766,7 @@ def test_get_program_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_program(request) # Establish that the response is the type that we expect. @@ -3798,6 +3808,7 @@ def test_get_program_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 = programs.Program.to_json(programs.Program()) req.return_value.content = return_value @@ -3840,6 +3851,7 @@ def test_list_programs_rest_bad_request(request_type=programs.ListProgramsReques 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_programs(request) @@ -3875,6 +3887,7 @@ def test_list_programs_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_programs(request) # Establish that the response is the type that we expect. @@ -3913,6 +3926,7 @@ def test_list_programs_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 = programs.ListProgramsResponse.to_json( programs.ListProgramsResponse() ) @@ -3957,6 +3971,7 @@ def test_enable_program_rest_bad_request(request_type=programs.EnableProgramRequ 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.enable_program(request) @@ -3995,6 +4010,7 @@ def test_enable_program_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.enable_program(request) # Establish that the response is the type that we expect. @@ -4036,6 +4052,7 @@ def test_enable_program_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 = programs.Program.to_json(programs.Program()) req.return_value.content = return_value @@ -4078,6 +4095,7 @@ def test_disable_program_rest_bad_request(request_type=programs.DisableProgramRe 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.disable_program(request) @@ -4116,6 +4134,7 @@ def test_disable_program_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.disable_program(request) # Establish that the response is the type that we expect. @@ -4157,6 +4176,7 @@ def test_disable_program_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 = programs.Program.to_json(programs.Program()) req.return_value.content = return_value diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_regions_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_regions_service.py index 3680f3e0ea32..9a2f58394544 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_regions_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_regions_service.py @@ -2987,6 +2987,7 @@ def test_get_region_rest_required_fields(request_type=regions.GetRegionRequest): 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_region(request) @@ -3032,6 +3033,7 @@ def test_get_region_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_region(**mock_args) @@ -3170,6 +3172,7 @@ def test_create_region_rest_required_fields(request_type=regions.CreateRegionReq 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_region(request) @@ -3232,6 +3235,7 @@ def test_create_region_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_region(**mock_args) @@ -3360,6 +3364,7 @@ def test_update_region_rest_required_fields(request_type=regions.UpdateRegionReq 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_region(request) @@ -3406,6 +3411,7 @@ def test_update_region_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_region(**mock_args) @@ -3533,6 +3539,7 @@ def test_delete_region_rest_required_fields(request_type=regions.DeleteRegionReq 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_region(request) @@ -3576,6 +3583,7 @@ def test_delete_region_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_region(**mock_args) @@ -3711,6 +3719,7 @@ def test_list_regions_rest_required_fields(request_type=regions.ListRegionsReque 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_regions(request) @@ -3764,6 +3773,7 @@ def test_list_regions_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_regions(**mock_args) @@ -4238,6 +4248,7 @@ def test_get_region_rest_bad_request(request_type=regions.GetRegionRequest): 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_region(request) @@ -4274,6 +4285,7 @@ def test_get_region_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_region(request) # Establish that the response is the type that we expect. @@ -4313,6 +4325,7 @@ def test_get_region_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 = regions.Region.to_json(regions.Region()) req.return_value.content = return_value @@ -4355,6 +4368,7 @@ def test_create_region_rest_bad_request(request_type=regions.CreateRegionRequest 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_region(request) @@ -4469,6 +4483,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_region(request) # Establish that the response is the type that we expect. @@ -4508,6 +4523,7 @@ def test_create_region_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 = regions.Region.to_json(regions.Region()) req.return_value.content = return_value @@ -4550,6 +4566,7 @@ def test_update_region_rest_bad_request(request_type=regions.UpdateRegionRequest 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_region(request) @@ -4664,6 +4681,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.update_region(request) # Establish that the response is the type that we expect. @@ -4703,6 +4721,7 @@ def test_update_region_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 = regions.Region.to_json(regions.Region()) req.return_value.content = return_value @@ -4745,6 +4764,7 @@ def test_delete_region_rest_bad_request(request_type=regions.DeleteRegionRequest 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_region(request) @@ -4775,6 +4795,7 @@ def test_delete_region_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_region(request) # Establish that the response is the type that we expect. @@ -4809,6 +4830,7 @@ def test_delete_region_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 = regions.DeleteRegionRequest() metadata = [ @@ -4847,6 +4869,7 @@ def test_list_regions_rest_bad_request(request_type=regions.ListRegionsRequest): 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_regions(request) @@ -4882,6 +4905,7 @@ def test_list_regions_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_regions(request) # Establish that the response is the type that we expect. @@ -4920,6 +4944,7 @@ def test_list_regions_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 = regions.ListRegionsResponse.to_json( regions.ListRegionsResponse() ) diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_shipping_settings_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_shipping_settings_service.py index 216144bcb0eb..c1e7127471a3 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_shipping_settings_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_shipping_settings_service.py @@ -1839,6 +1839,7 @@ def test_get_shipping_settings_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_shipping_settings(request) @@ -1884,6 +1885,7 @@ def test_get_shipping_settings_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_shipping_settings(**mock_args) @@ -2021,6 +2023,7 @@ def test_insert_shipping_settings_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.insert_shipping_settings(request) @@ -2300,6 +2303,7 @@ def test_get_shipping_settings_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.get_shipping_settings(request) @@ -2336,6 +2340,7 @@ def test_get_shipping_settings_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_shipping_settings(request) # Establish that the response is the type that we expect. @@ -2377,6 +2382,7 @@ def test_get_shipping_settings_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 = shippingsettings.ShippingSettings.to_json( shippingsettings.ShippingSettings() ) @@ -2423,6 +2429,7 @@ def test_insert_shipping_settings_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.insert_shipping_settings(request) @@ -2676,6 +2683,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.insert_shipping_settings(request) # Establish that the response is the type that we expect. @@ -2719,6 +2727,7 @@ def test_insert_shipping_settings_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 = shippingsettings.ShippingSettings.to_json( shippingsettings.ShippingSettings() ) diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_terms_of_service_agreement_state_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_terms_of_service_agreement_state_service.py index 883eb63e8267..e4d378bac349 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_terms_of_service_agreement_state_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_terms_of_service_agreement_state_service.py @@ -2043,6 +2043,7 @@ def test_get_terms_of_service_agreement_state_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_terms_of_service_agreement_state(request) @@ -2094,6 +2095,7 @@ def test_get_terms_of_service_agreement_state_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_terms_of_service_agreement_state(**mock_args) @@ -2238,6 +2240,7 @@ def test_retrieve_for_application_terms_of_service_agreement_state_rest_required 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.retrieve_for_application_terms_of_service_agreement_state( request @@ -2289,6 +2292,7 @@ def test_retrieve_for_application_terms_of_service_agreement_state_rest_flattene 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.retrieve_for_application_terms_of_service_agreement_state(**mock_args) @@ -2592,6 +2596,7 @@ def test_get_terms_of_service_agreement_state_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.get_terms_of_service_agreement_state(request) @@ -2631,6 +2636,7 @@ def test_get_terms_of_service_agreement_state_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_terms_of_service_agreement_state(request) # Establish that the response is the type that we expect. @@ -2682,6 +2688,7 @@ def test_get_terms_of_service_agreement_state_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 = ( termsofserviceagreementstate.TermsOfServiceAgreementState.to_json( termsofserviceagreementstate.TermsOfServiceAgreementState() @@ -2730,6 +2737,7 @@ def test_retrieve_for_application_terms_of_service_agreement_state_rest_bad_requ 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.retrieve_for_application_terms_of_service_agreement_state(request) @@ -2771,6 +2779,7 @@ def test_retrieve_for_application_terms_of_service_agreement_state_rest_call_suc 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.retrieve_for_application_terms_of_service_agreement_state( request ) @@ -2824,6 +2833,7 @@ def test_retrieve_for_application_terms_of_service_agreement_state_rest_intercep 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 = ( termsofserviceagreementstate.TermsOfServiceAgreementState.to_json( termsofserviceagreementstate.TermsOfServiceAgreementState() diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_terms_of_service_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_terms_of_service_service.py index 231ce2fb4c85..4ef61688bdb6 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_terms_of_service_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_terms_of_service_service.py @@ -2133,6 +2133,7 @@ def test_get_terms_of_service_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_terms_of_service(request) @@ -2178,6 +2179,7 @@ def test_get_terms_of_service_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_terms_of_service(**mock_args) @@ -2323,6 +2325,7 @@ def test_retrieve_latest_terms_of_service_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.retrieve_latest_terms_of_service(request) @@ -2486,6 +2489,7 @@ def test_accept_terms_of_service_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.accept_terms_of_service(request) @@ -2553,6 +2557,7 @@ def test_accept_terms_of_service_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.accept_terms_of_service(**mock_args) @@ -2890,6 +2895,7 @@ def test_get_terms_of_service_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.get_terms_of_service(request) @@ -2929,6 +2935,7 @@ def test_get_terms_of_service_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_terms_of_service(request) # Establish that the response is the type that we expect. @@ -2973,6 +2980,7 @@ def test_get_terms_of_service_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 = termsofservice.TermsOfService.to_json( termsofservice.TermsOfService() ) @@ -3019,6 +3027,7 @@ def test_retrieve_latest_terms_of_service_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.retrieve_latest_terms_of_service(request) @@ -3058,6 +3067,7 @@ def test_retrieve_latest_terms_of_service_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.retrieve_latest_terms_of_service(request) # Establish that the response is the type that we expect. @@ -3104,6 +3114,7 @@ def test_retrieve_latest_terms_of_service_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 = termsofservice.TermsOfService.to_json( termsofservice.TermsOfService() ) @@ -3150,6 +3161,7 @@ def test_accept_terms_of_service_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.accept_terms_of_service(request) @@ -3180,6 +3192,7 @@ def test_accept_terms_of_service_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.accept_terms_of_service(request) # Establish that the response is the type that we expect. @@ -3216,6 +3229,7 @@ def test_accept_terms_of_service_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 = termsofservice.AcceptTermsOfServiceRequest() metadata = [ diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_user_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_user_service.py index 717391fcc580..79b7be920ccc 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_user_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_user_service.py @@ -2951,6 +2951,7 @@ def test_get_user_rest_required_fields(request_type=user.GetUserRequest): 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_user(request) @@ -2996,6 +2997,7 @@ def test_get_user_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_user(**mock_args) @@ -3134,6 +3136,7 @@ def test_create_user_rest_required_fields(request_type=gsma_user.CreateUserReque 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_user(request) @@ -3195,6 +3198,7 @@ def test_create_user_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_user(**mock_args) @@ -3321,6 +3325,7 @@ def test_delete_user_rest_required_fields(request_type=user.DeleteUserRequest): 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_user(request) @@ -3364,6 +3369,7 @@ def test_delete_user_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_user(**mock_args) @@ -3490,6 +3496,7 @@ def test_update_user_rest_required_fields(request_type=gsma_user.UpdateUserReque 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_user(request) @@ -3544,6 +3551,7 @@ def test_update_user_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_user(**mock_args) @@ -3681,6 +3689,7 @@ def test_list_users_rest_required_fields(request_type=user.ListUsersRequest): 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_users(request) @@ -3734,6 +3743,7 @@ def test_list_users_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_users(**mock_args) @@ -4211,6 +4221,7 @@ def test_get_user_rest_bad_request(request_type=user.GetUserRequest): 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_user(request) @@ -4248,6 +4259,7 @@ def test_get_user_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_user(request) # Establish that the response is the type that we expect. @@ -4288,6 +4300,7 @@ def test_get_user_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 = user.User.to_json(user.User()) req.return_value.content = return_value @@ -4330,6 +4343,7 @@ def test_create_user_rest_bad_request(request_type=gsma_user.CreateUserRequest): 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_user(request) @@ -4435,6 +4449,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_user(request) # Establish that the response is the type that we expect. @@ -4475,6 +4490,7 @@ def test_create_user_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 = gsma_user.User.to_json(gsma_user.User()) req.return_value.content = return_value @@ -4517,6 +4533,7 @@ def test_delete_user_rest_bad_request(request_type=user.DeleteUserRequest): 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_user(request) @@ -4547,6 +4564,7 @@ def test_delete_user_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_user(request) # Establish that the response is the type that we expect. @@ -4581,6 +4599,7 @@ def test_delete_user_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 = user.DeleteUserRequest() metadata = [ @@ -4619,6 +4638,7 @@ def test_update_user_rest_bad_request(request_type=gsma_user.UpdateUserRequest): 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_user(request) @@ -4728,6 +4748,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.update_user(request) # Establish that the response is the type that we expect. @@ -4768,6 +4789,7 @@ def test_update_user_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 = gsma_user.User.to_json(gsma_user.User()) req.return_value.content = return_value @@ -4810,6 +4832,7 @@ def test_list_users_rest_bad_request(request_type=user.ListUsersRequest): 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_users(request) @@ -4845,6 +4868,7 @@ def test_list_users_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_users(request) # Establish that the response is the type that we expect. @@ -4883,6 +4907,7 @@ def test_list_users_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 = user.ListUsersResponse.to_json(user.ListUsersResponse()) req.return_value.content = return_value diff --git a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions/gapic_version.py b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions/gapic_version.py index e9c4bb5650f3..558c8aab67c5 100644 --- a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions/gapic_version.py +++ b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.5" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/gapic_version.py b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/gapic_version.py index e9c4bb5650f3..558c8aab67c5 100644 --- a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/gapic_version.py +++ b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.5" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/async_client.py b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/async_client.py index d3c1bcfc9094..4029d24bcafb 100644 --- a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/async_client.py +++ b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -54,6 +55,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, ConversionSourcesServiceTransport from .transports.grpc_asyncio import ConversionSourcesServiceGrpcAsyncIOTransport +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 ConversionSourcesServiceAsyncClient: """Service for managing conversion sources for a merchant @@ -275,6 +285,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.shopping.merchant.conversions_v1beta.ConversionSourcesServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.conversions.v1beta.ConversionSourcesService", + "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.shopping.merchant.conversions.v1beta.ConversionSourcesService", + "credentialsType": None, + }, + ) + async def create_conversion_source( self, request: Optional[ @@ -285,7 +317,7 @@ async def create_conversion_source( conversion_source: Optional[conversionsources.ConversionSource] = 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]]] = (), ) -> conversionsources.ConversionSource: r"""Creates a new conversion source. @@ -343,8 +375,10 @@ async def sample_create_conversion_source(): 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.shopping.merchant_conversions_v1beta.types.ConversionSource: @@ -412,7 +446,7 @@ async def update_conversion_source( 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]]] = (), ) -> conversionsources.ConversionSource: r"""Updates information of an existing conversion source. Available only for Merchant Center Destination @@ -469,8 +503,10 @@ async def sample_update_conversion_source(): 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.shopping.merchant_conversions_v1beta.types.ConversionSource: @@ -539,7 +575,7 @@ async def delete_conversion_source( 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"""Archives an existing conversion source. If the conversion source is a Merchant Center Destination, it @@ -585,8 +621,10 @@ async def sample_delete_conversion_source(): 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 @@ -639,7 +677,7 @@ async def undelete_conversion_source( *, 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]]] = (), ) -> conversionsources.ConversionSource: r"""Re-enables an archived conversion source. Only Available for Merchant Center Destination conversion @@ -678,8 +716,10 @@ async def sample_undelete_conversion_source(): 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.shopping.merchant_conversions_v1beta.types.ConversionSource: @@ -730,7 +770,7 @@ async def get_conversion_source( 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]]] = (), ) -> conversionsources.ConversionSource: r"""Fetches a conversion source. @@ -775,8 +815,10 @@ async def sample_get_conversion_source(): 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.shopping.merchant_conversions_v1beta.types.ConversionSource: @@ -841,7 +883,7 @@ async def list_conversion_sources( 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.ListConversionSourcesAsyncPager: r"""Retrieves the list of conversion sources the caller has access to. @@ -888,8 +930,10 @@ async def sample_list_conversion_sources(): 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.shopping.merchant_conversions_v1beta.services.conversion_sources_service.pagers.ListConversionSourcesAsyncPager: diff --git a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/client.py b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/client.py index b2bdc63a6116..980bba28a6dc 100644 --- a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/client.py +++ b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.protobuf import field_mask_pb2 # type: ignore from google.protobuf import timestamp_pb2 # type: ignore @@ -591,6 +601,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( @@ -657,6 +671,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.shopping.merchant.conversions_v1beta.ConversionSourcesServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.conversions.v1beta.ConversionSourcesService", + "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.shopping.merchant.conversions.v1beta.ConversionSourcesService", + "credentialsType": None, + }, + ) + def create_conversion_source( self, request: Optional[ @@ -667,7 +704,7 @@ def create_conversion_source( conversion_source: Optional[conversionsources.ConversionSource] = 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]]] = (), ) -> conversionsources.ConversionSource: r"""Creates a new conversion source. @@ -725,8 +762,10 @@ def sample_create_conversion_source(): 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.shopping.merchant_conversions_v1beta.types.ConversionSource: @@ -791,7 +830,7 @@ def update_conversion_source( 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]]] = (), ) -> conversionsources.ConversionSource: r"""Updates information of an existing conversion source. Available only for Merchant Center Destination @@ -848,8 +887,10 @@ def sample_update_conversion_source(): 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.shopping.merchant_conversions_v1beta.types.ConversionSource: @@ -915,7 +956,7 @@ def delete_conversion_source( 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"""Archives an existing conversion source. If the conversion source is a Merchant Center Destination, it @@ -961,8 +1002,10 @@ def sample_delete_conversion_source(): 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 @@ -1012,7 +1055,7 @@ def undelete_conversion_source( *, 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]]] = (), ) -> conversionsources.ConversionSource: r"""Re-enables an archived conversion source. Only Available for Merchant Center Destination conversion @@ -1051,8 +1094,10 @@ def sample_undelete_conversion_source(): 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.shopping.merchant_conversions_v1beta.types.ConversionSource: @@ -1103,7 +1148,7 @@ def get_conversion_source( 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]]] = (), ) -> conversionsources.ConversionSource: r"""Fetches a conversion source. @@ -1148,8 +1193,10 @@ def sample_get_conversion_source(): 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.shopping.merchant_conversions_v1beta.types.ConversionSource: @@ -1211,7 +1258,7 @@ def list_conversion_sources( 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.ListConversionSourcesPager: r"""Retrieves the list of conversion sources the caller has access to. @@ -1258,8 +1305,10 @@ def sample_list_conversion_sources(): 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.shopping.merchant_conversions_v1beta.services.conversion_sources_service.pagers.ListConversionSourcesPager: diff --git a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/pagers.py b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/pagers.py index 0673a126f913..6ed9744f1466 100644 --- a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/pagers.py +++ b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/pagers.py @@ -67,7 +67,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. @@ -81,8 +81,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 = conversionsources.ListConversionSourcesRequest(request) @@ -143,7 +145,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. @@ -157,8 +159,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 = conversionsources.ListConversionSourcesRequest(request) diff --git a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/grpc.py b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/grpc.py index f46de3fcccda..0cc21aa5b952 100644 --- a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/grpc.py +++ b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -21,12 +24,90 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore +import proto # type: ignore from google.shopping.merchant_conversions_v1beta.types import conversionsources from .base import DEFAULT_CLIENT_INFO, ConversionSourcesServiceTransport +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.shopping.merchant.conversions.v1beta.ConversionSourcesService", + "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.shopping.merchant.conversions.v1beta.ConversionSourcesService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class ConversionSourcesServiceGrpcTransport(ConversionSourcesServiceTransport): """gRPC backend transport for ConversionSourcesService. @@ -181,7 +262,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 @@ -258,7 +344,7 @@ def create_conversion_source( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_conversion_source" not in self._stubs: - self._stubs["create_conversion_source"] = self.grpc_channel.unary_unary( + self._stubs["create_conversion_source"] = self._logged_channel.unary_unary( "/google.shopping.merchant.conversions.v1beta.ConversionSourcesService/CreateConversionSource", request_serializer=conversionsources.CreateConversionSourceRequest.serialize, response_deserializer=conversionsources.ConversionSource.deserialize, @@ -289,7 +375,7 @@ def update_conversion_source( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_conversion_source" not in self._stubs: - self._stubs["update_conversion_source"] = self.grpc_channel.unary_unary( + self._stubs["update_conversion_source"] = self._logged_channel.unary_unary( "/google.shopping.merchant.conversions.v1beta.ConversionSourcesService/UpdateConversionSource", request_serializer=conversionsources.UpdateConversionSourceRequest.serialize, response_deserializer=conversionsources.ConversionSource.deserialize, @@ -319,7 +405,7 @@ def delete_conversion_source( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_conversion_source" not in self._stubs: - self._stubs["delete_conversion_source"] = self.grpc_channel.unary_unary( + self._stubs["delete_conversion_source"] = self._logged_channel.unary_unary( "/google.shopping.merchant.conversions.v1beta.ConversionSourcesService/DeleteConversionSource", request_serializer=conversionsources.DeleteConversionSourceRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -350,7 +436,9 @@ def undelete_conversion_source( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "undelete_conversion_source" not in self._stubs: - self._stubs["undelete_conversion_source"] = self.grpc_channel.unary_unary( + self._stubs[ + "undelete_conversion_source" + ] = self._logged_channel.unary_unary( "/google.shopping.merchant.conversions.v1beta.ConversionSourcesService/UndeleteConversionSource", request_serializer=conversionsources.UndeleteConversionSourceRequest.serialize, response_deserializer=conversionsources.ConversionSource.deserialize, @@ -379,7 +467,7 @@ def get_conversion_source( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_conversion_source" not in self._stubs: - self._stubs["get_conversion_source"] = self.grpc_channel.unary_unary( + self._stubs["get_conversion_source"] = self._logged_channel.unary_unary( "/google.shopping.merchant.conversions.v1beta.ConversionSourcesService/GetConversionSource", request_serializer=conversionsources.GetConversionSourceRequest.serialize, response_deserializer=conversionsources.ConversionSource.deserialize, @@ -409,7 +497,7 @@ def list_conversion_sources( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_conversion_sources" not in self._stubs: - self._stubs["list_conversion_sources"] = self.grpc_channel.unary_unary( + self._stubs["list_conversion_sources"] = self._logged_channel.unary_unary( "/google.shopping.merchant.conversions.v1beta.ConversionSourcesService/ListConversionSources", request_serializer=conversionsources.ListConversionSourcesRequest.serialize, response_deserializer=conversionsources.ListConversionSourcesResponse.deserialize, @@ -417,7 +505,7 @@ def list_conversion_sources( return self._stubs["list_conversion_sources"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/grpc_asyncio.py index 4da59395d836..50c0f6409ce7 100644 --- a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -23,14 +26,93 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_conversions_v1beta.types import conversionsources from .base import DEFAULT_CLIENT_INFO, ConversionSourcesServiceTransport from .grpc import ConversionSourcesServiceGrpcTransport +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.shopping.merchant.conversions.v1beta.ConversionSourcesService", + "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.shopping.merchant.conversions.v1beta.ConversionSourcesService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class ConversionSourcesServiceGrpcAsyncIOTransport(ConversionSourcesServiceTransport): """gRPC AsyncIO backend transport for ConversionSourcesService. @@ -228,10 +310,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 @@ -266,7 +351,7 @@ def create_conversion_source( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_conversion_source" not in self._stubs: - self._stubs["create_conversion_source"] = self.grpc_channel.unary_unary( + self._stubs["create_conversion_source"] = self._logged_channel.unary_unary( "/google.shopping.merchant.conversions.v1beta.ConversionSourcesService/CreateConversionSource", request_serializer=conversionsources.CreateConversionSourceRequest.serialize, response_deserializer=conversionsources.ConversionSource.deserialize, @@ -297,7 +382,7 @@ def update_conversion_source( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_conversion_source" not in self._stubs: - self._stubs["update_conversion_source"] = self.grpc_channel.unary_unary( + self._stubs["update_conversion_source"] = self._logged_channel.unary_unary( "/google.shopping.merchant.conversions.v1beta.ConversionSourcesService/UpdateConversionSource", request_serializer=conversionsources.UpdateConversionSourceRequest.serialize, response_deserializer=conversionsources.ConversionSource.deserialize, @@ -329,7 +414,7 @@ def delete_conversion_source( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_conversion_source" not in self._stubs: - self._stubs["delete_conversion_source"] = self.grpc_channel.unary_unary( + self._stubs["delete_conversion_source"] = self._logged_channel.unary_unary( "/google.shopping.merchant.conversions.v1beta.ConversionSourcesService/DeleteConversionSource", request_serializer=conversionsources.DeleteConversionSourceRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -360,7 +445,9 @@ def undelete_conversion_source( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "undelete_conversion_source" not in self._stubs: - self._stubs["undelete_conversion_source"] = self.grpc_channel.unary_unary( + self._stubs[ + "undelete_conversion_source" + ] = self._logged_channel.unary_unary( "/google.shopping.merchant.conversions.v1beta.ConversionSourcesService/UndeleteConversionSource", request_serializer=conversionsources.UndeleteConversionSourceRequest.serialize, response_deserializer=conversionsources.ConversionSource.deserialize, @@ -389,7 +476,7 @@ def get_conversion_source( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_conversion_source" not in self._stubs: - self._stubs["get_conversion_source"] = self.grpc_channel.unary_unary( + self._stubs["get_conversion_source"] = self._logged_channel.unary_unary( "/google.shopping.merchant.conversions.v1beta.ConversionSourcesService/GetConversionSource", request_serializer=conversionsources.GetConversionSourceRequest.serialize, response_deserializer=conversionsources.ConversionSource.deserialize, @@ -419,7 +506,7 @@ def list_conversion_sources( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_conversion_sources" not in self._stubs: - self._stubs["list_conversion_sources"] = self.grpc_channel.unary_unary( + self._stubs["list_conversion_sources"] = self._logged_channel.unary_unary( "/google.shopping.merchant.conversions.v1beta.ConversionSourcesService/ListConversionSources", request_serializer=conversionsources.ListConversionSourcesRequest.serialize, response_deserializer=conversionsources.ListConversionSourcesResponse.deserialize, @@ -467,7 +554,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/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/rest.py b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/rest.py index 0aeab813fb6a..93fb6bd34cd2 100644 --- a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/rest.py +++ b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -38,6 +38,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, @@ -114,9 +122,10 @@ def post_update_conversion_source(self, response): def pre_create_conversion_source( self, request: conversionsources.CreateConversionSourceRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - conversionsources.CreateConversionSourceRequest, Sequence[Tuple[str, str]] + conversionsources.CreateConversionSourceRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for create_conversion_source @@ -139,9 +148,10 @@ def post_create_conversion_source( def pre_delete_conversion_source( self, request: conversionsources.DeleteConversionSourceRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - conversionsources.DeleteConversionSourceRequest, Sequence[Tuple[str, str]] + conversionsources.DeleteConversionSourceRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for delete_conversion_source @@ -153,8 +163,11 @@ def pre_delete_conversion_source( def pre_get_conversion_source( self, request: conversionsources.GetConversionSourceRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[conversionsources.GetConversionSourceRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversionsources.GetConversionSourceRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: """Pre-rpc interceptor for get_conversion_source Override in a subclass to manipulate the request or metadata @@ -176,9 +189,10 @@ def post_get_conversion_source( def pre_list_conversion_sources( self, request: conversionsources.ListConversionSourcesRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - conversionsources.ListConversionSourcesRequest, Sequence[Tuple[str, str]] + conversionsources.ListConversionSourcesRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for list_conversion_sources @@ -201,9 +215,10 @@ def post_list_conversion_sources( def pre_undelete_conversion_source( self, request: conversionsources.UndeleteConversionSourceRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - conversionsources.UndeleteConversionSourceRequest, Sequence[Tuple[str, str]] + conversionsources.UndeleteConversionSourceRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for undelete_conversion_source @@ -226,9 +241,10 @@ def post_undelete_conversion_source( def pre_update_conversion_source( self, request: conversionsources.UpdateConversionSourceRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - conversionsources.UpdateConversionSourceRequest, Sequence[Tuple[str, str]] + conversionsources.UpdateConversionSourceRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for update_conversion_source @@ -372,7 +388,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]]] = (), ) -> conversionsources.ConversionSource: r"""Call the create conversion source method over HTTP. @@ -383,8 +399,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: ~.conversionsources.ConversionSource: @@ -398,6 +416,7 @@ def __call__( http_options = ( _BaseConversionSourcesServiceRestTransport._BaseCreateConversionSource._get_http_options() ) + request, metadata = self._interceptor.pre_create_conversion_source( request, metadata ) @@ -414,6 +433,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.shopping.merchant.conversions_v1beta.ConversionSourcesServiceClient.CreateConversionSource", + extra={ + "serviceName": "google.shopping.merchant.conversions.v1beta.ConversionSourcesService", + "rpcName": "CreateConversionSource", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ConversionSourcesServiceRestTransport._CreateConversionSource._get_response( self._host, @@ -435,7 +481,31 @@ def __call__( pb_resp = conversionsources.ConversionSource.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_conversion_source(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = conversionsources.ConversionSource.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.shopping.merchant.conversions_v1beta.ConversionSourcesServiceClient.create_conversion_source", + extra={ + "serviceName": "google.shopping.merchant.conversions.v1beta.ConversionSourcesService", + "rpcName": "CreateConversionSource", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _DeleteConversionSource( @@ -473,7 +543,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 conversion source method over HTTP. @@ -484,13 +554,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 = ( _BaseConversionSourcesServiceRestTransport._BaseDeleteConversionSource._get_http_options() ) + request, metadata = self._interceptor.pre_delete_conversion_source( request, metadata ) @@ -503,6 +576,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.shopping.merchant.conversions_v1beta.ConversionSourcesServiceClient.DeleteConversionSource", + extra={ + "serviceName": "google.shopping.merchant.conversions.v1beta.ConversionSourcesService", + "rpcName": "DeleteConversionSource", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ConversionSourcesServiceRestTransport._DeleteConversionSource._get_response( self._host, @@ -553,7 +653,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]]] = (), ) -> conversionsources.ConversionSource: r"""Call the get conversion source method over HTTP. @@ -564,8 +664,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: ~.conversionsources.ConversionSource: @@ -579,6 +681,7 @@ def __call__( http_options = ( _BaseConversionSourcesServiceRestTransport._BaseGetConversionSource._get_http_options() ) + request, metadata = self._interceptor.pre_get_conversion_source( request, metadata ) @@ -591,6 +694,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.shopping.merchant.conversions_v1beta.ConversionSourcesServiceClient.GetConversionSource", + extra={ + "serviceName": "google.shopping.merchant.conversions.v1beta.ConversionSourcesService", + "rpcName": "GetConversionSource", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ConversionSourcesServiceRestTransport._GetConversionSource._get_response( self._host, @@ -611,7 +741,31 @@ def __call__( pb_resp = conversionsources.ConversionSource.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_conversion_source(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = conversionsources.ConversionSource.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.shopping.merchant.conversions_v1beta.ConversionSourcesServiceClient.get_conversion_source", + extra={ + "serviceName": "google.shopping.merchant.conversions.v1beta.ConversionSourcesService", + "rpcName": "GetConversionSource", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListConversionSources( @@ -649,7 +803,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]]] = (), ) -> conversionsources.ListConversionSourcesResponse: r"""Call the list conversion sources method over HTTP. @@ -660,8 +814,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: ~.conversionsources.ListConversionSourcesResponse: @@ -673,6 +829,7 @@ def __call__( http_options = ( _BaseConversionSourcesServiceRestTransport._BaseListConversionSources._get_http_options() ) + request, metadata = self._interceptor.pre_list_conversion_sources( request, metadata ) @@ -685,6 +842,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.shopping.merchant.conversions_v1beta.ConversionSourcesServiceClient.ListConversionSources", + extra={ + "serviceName": "google.shopping.merchant.conversions.v1beta.ConversionSourcesService", + "rpcName": "ListConversionSources", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ConversionSourcesServiceRestTransport._ListConversionSources._get_response( self._host, @@ -705,7 +889,33 @@ def __call__( pb_resp = conversionsources.ListConversionSourcesResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_conversion_sources(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + conversionsources.ListConversionSourcesResponse.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.shopping.merchant.conversions_v1beta.ConversionSourcesServiceClient.list_conversion_sources", + extra={ + "serviceName": "google.shopping.merchant.conversions.v1beta.ConversionSourcesService", + "rpcName": "ListConversionSources", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _UndeleteConversionSource( @@ -746,7 +956,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]]] = (), ) -> conversionsources.ConversionSource: r"""Call the undelete conversion source method over HTTP. @@ -758,8 +968,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: ~.conversionsources.ConversionSource: @@ -773,6 +985,7 @@ def __call__( http_options = ( _BaseConversionSourcesServiceRestTransport._BaseUndeleteConversionSource._get_http_options() ) + request, metadata = self._interceptor.pre_undelete_conversion_source( request, metadata ) @@ -789,6 +1002,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.shopping.merchant.conversions_v1beta.ConversionSourcesServiceClient.UndeleteConversionSource", + extra={ + "serviceName": "google.shopping.merchant.conversions.v1beta.ConversionSourcesService", + "rpcName": "UndeleteConversionSource", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ConversionSourcesServiceRestTransport._UndeleteConversionSource._get_response( self._host, @@ -810,7 +1050,31 @@ def __call__( pb_resp = conversionsources.ConversionSource.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_undelete_conversion_source(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = conversionsources.ConversionSource.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.shopping.merchant.conversions_v1beta.ConversionSourcesServiceClient.undelete_conversion_source", + extra={ + "serviceName": "google.shopping.merchant.conversions.v1beta.ConversionSourcesService", + "rpcName": "UndeleteConversionSource", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _UpdateConversionSource( @@ -849,7 +1113,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]]] = (), ) -> conversionsources.ConversionSource: r"""Call the update conversion source method over HTTP. @@ -860,8 +1124,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: ~.conversionsources.ConversionSource: @@ -875,6 +1141,7 @@ def __call__( http_options = ( _BaseConversionSourcesServiceRestTransport._BaseUpdateConversionSource._get_http_options() ) + request, metadata = self._interceptor.pre_update_conversion_source( request, metadata ) @@ -891,6 +1158,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.shopping.merchant.conversions_v1beta.ConversionSourcesServiceClient.UpdateConversionSource", + extra={ + "serviceName": "google.shopping.merchant.conversions.v1beta.ConversionSourcesService", + "rpcName": "UpdateConversionSource", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ConversionSourcesServiceRestTransport._UpdateConversionSource._get_response( self._host, @@ -912,7 +1206,31 @@ def __call__( pb_resp = conversionsources.ConversionSource.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_conversion_source(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = conversionsources.ConversionSource.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.shopping.merchant.conversions_v1beta.ConversionSourcesServiceClient.update_conversion_source", + extra={ + "serviceName": "google.shopping.merchant.conversions.v1beta.ConversionSourcesService", + "rpcName": "UpdateConversionSource", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-conversions/samples/generated_samples/snippet_metadata_google.shopping.merchant.conversions.v1beta.json b/packages/google-shopping-merchant-conversions/samples/generated_samples/snippet_metadata_google.shopping.merchant.conversions.v1beta.json index f4c02f3b5464..7b979a5c445b 100644 --- a/packages/google-shopping-merchant-conversions/samples/generated_samples/snippet_metadata_google.shopping.merchant.conversions.v1beta.json +++ b/packages/google-shopping-merchant-conversions/samples/generated_samples/snippet_metadata_google.shopping.merchant.conversions.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-shopping-merchant-conversions", - "version": "0.1.5" + "version": "0.1.0" }, "snippets": [ { @@ -51,7 +51,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_conversions_v1beta.types.ConversionSource", @@ -135,7 +135,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_conversions_v1beta.types.ConversionSource", @@ -216,7 +216,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_conversion_source" @@ -293,7 +293,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_conversion_source" @@ -371,7 +371,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_conversions_v1beta.types.ConversionSource", @@ -451,7 +451,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_conversions_v1beta.types.ConversionSource", @@ -532,7 +532,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_conversions_v1beta.services.conversion_sources_service.pagers.ListConversionSourcesAsyncPager", @@ -612,7 +612,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_conversions_v1beta.services.conversion_sources_service.pagers.ListConversionSourcesPager", @@ -689,7 +689,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_conversions_v1beta.types.ConversionSource", @@ -765,7 +765,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_conversions_v1beta.types.ConversionSource", @@ -850,7 +850,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_conversions_v1beta.types.ConversionSource", @@ -934,7 +934,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_conversions_v1beta.types.ConversionSource", diff --git a/packages/google-shopping-merchant-conversions/tests/unit/gapic/merchant_conversions_v1beta/test_conversion_sources_service.py b/packages/google-shopping-merchant-conversions/tests/unit/gapic/merchant_conversions_v1beta/test_conversion_sources_service.py index e014561c7cb8..740d263c45c6 100644 --- a/packages/google-shopping-merchant-conversions/tests/unit/gapic/merchant_conversions_v1beta/test_conversion_sources_service.py +++ b/packages/google-shopping-merchant-conversions/tests/unit/gapic/merchant_conversions_v1beta/test_conversion_sources_service.py @@ -3500,6 +3500,7 @@ def test_create_conversion_source_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_conversion_source(request) @@ -3558,6 +3559,7 @@ def test_create_conversion_source_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_conversion_source(**mock_args) @@ -3697,6 +3699,7 @@ def test_update_conversion_source_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_conversion_source(request) @@ -3757,6 +3760,7 @@ def test_update_conversion_source_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_conversion_source(**mock_args) @@ -3895,6 +3899,7 @@ def test_delete_conversion_source_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_conversion_source(request) @@ -3938,6 +3943,7 @@ def test_delete_conversion_source_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_conversion_source(**mock_args) @@ -4075,6 +4081,7 @@ def test_undelete_conversion_source_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.undelete_conversion_source(request) @@ -4199,6 +4206,7 @@ def test_get_conversion_source_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_conversion_source(request) @@ -4244,6 +4252,7 @@ def test_get_conversion_source_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_conversion_source(**mock_args) @@ -4390,6 +4399,7 @@ def test_list_conversion_sources_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_conversion_sources(request) @@ -4444,6 +4454,7 @@ def test_list_conversion_sources_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_conversion_sources(**mock_args) @@ -5000,6 +5011,7 @@ def test_create_conversion_source_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.create_conversion_source(request) @@ -5127,6 +5139,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_conversion_source(request) # Establish that the response is the type that we expect. @@ -5171,6 +5184,7 @@ def test_create_conversion_source_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 = conversionsources.ConversionSource.to_json( conversionsources.ConversionSource() ) @@ -5219,6 +5233,7 @@ def test_update_conversion_source_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_conversion_source(request) @@ -5348,6 +5363,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.update_conversion_source(request) # Establish that the response is the type that we expect. @@ -5392,6 +5408,7 @@ def test_update_conversion_source_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 = conversionsources.ConversionSource.to_json( conversionsources.ConversionSource() ) @@ -5438,6 +5455,7 @@ def test_delete_conversion_source_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_conversion_source(request) @@ -5468,6 +5486,7 @@ def test_delete_conversion_source_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_conversion_source(request) # Establish that the response is the type that we expect. @@ -5505,6 +5524,7 @@ def test_delete_conversion_source_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 = conversionsources.DeleteConversionSourceRequest() metadata = [ @@ -5545,6 +5565,7 @@ def test_undelete_conversion_source_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.undelete_conversion_source(request) @@ -5582,6 +5603,7 @@ def test_undelete_conversion_source_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.undelete_conversion_source(request) # Establish that the response is the type that we expect. @@ -5626,6 +5648,7 @@ def test_undelete_conversion_source_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 = conversionsources.ConversionSource.to_json( conversionsources.ConversionSource() ) @@ -5672,6 +5695,7 @@ def test_get_conversion_source_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.get_conversion_source(request) @@ -5709,6 +5733,7 @@ def test_get_conversion_source_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_conversion_source(request) # Establish that the response is the type that we expect. @@ -5751,6 +5776,7 @@ def test_get_conversion_source_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 = conversionsources.ConversionSource.to_json( conversionsources.ConversionSource() ) @@ -5797,6 +5823,7 @@ def test_list_conversion_sources_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_conversion_sources(request) @@ -5832,6 +5859,7 @@ def test_list_conversion_sources_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_conversion_sources(request) # Establish that the response is the type that we expect. @@ -5874,6 +5902,7 @@ def test_list_conversion_sources_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 = conversionsources.ListConversionSourcesResponse.to_json( conversionsources.ListConversionSourcesResponse() ) diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources/gapic_version.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources/gapic_version.py index e9c4bb5650f3..558c8aab67c5 100644 --- a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources/gapic_version.py +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.5" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/gapic_version.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/gapic_version.py index e9c4bb5650f3..558c8aab67c5 100644 --- a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/gapic_version.py +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.5" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/async_client.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/async_client.py index 89103d087586..f7d44f13c10e 100644 --- a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/async_client.py +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -57,6 +58,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, DataSourcesServiceTransport from .transports.grpc_asyncio import DataSourcesServiceGrpcAsyncIOTransport +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 DataSourcesServiceAsyncClient: """Service to manage primary, supplemental, inventory and other data @@ -272,6 +282,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.shopping.merchant.datasources_v1beta.DataSourcesServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.datasources.v1beta.DataSourcesService", + "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.shopping.merchant.datasources.v1beta.DataSourcesService", + "credentialsType": None, + }, + ) + async def get_data_source( self, request: Optional[Union[datasources.GetDataSourceRequest, dict]] = None, @@ -279,7 +311,7 @@ async def get_data_source( 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]]] = (), ) -> datasources.DataSource: r"""Retrieves the data source configuration for the given account. @@ -324,8 +356,10 @@ async def sample_get_data_source(): 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.shopping.merchant_datasources_v1beta.types.DataSource: @@ -386,7 +420,7 @@ async def list_data_sources( 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.ListDataSourcesAsyncPager: r"""Lists the configurations for data sources for the given account. @@ -432,8 +466,10 @@ async def sample_list_data_sources(): 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.shopping.merchant_datasources_v1beta.services.data_sources_service.pagers.ListDataSourcesAsyncPager: @@ -509,7 +545,7 @@ async def create_data_source( data_source: Optional[datasources.DataSource] = 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]]] = (), ) -> datasources.DataSource: r"""Creates the new data source configuration for the given account. @@ -564,8 +600,10 @@ async def sample_create_data_source(): 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.shopping.merchant_datasources_v1beta.types.DataSource: @@ -629,7 +667,7 @@ async def update_data_source( 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]]] = (), ) -> datasources.DataSource: r"""Updates the existing data source configuration. The fields that are set in the update mask but not provided @@ -692,8 +730,10 @@ async def sample_update_data_source(): 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.shopping.merchant_datasources_v1beta.types.DataSource: @@ -758,7 +798,7 @@ async def delete_data_source( 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 data source from your Merchant Center account. @@ -800,8 +840,10 @@ async def sample_delete_data_source(): 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 @@ -852,7 +894,7 @@ async def fetch_data_source( *, 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"""Performs the data fetch immediately (even outside fetch schedule) on a data source from your Merchant @@ -892,8 +934,10 @@ async def sample_fetch_data_source(): 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. # - Use the request object if provided (there's no risk of modifying the input as diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/client.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/client.py index 19366f1171b2..e3b7638db779 100644 --- a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/client.py +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.protobuf import field_mask_pb2 # type: ignore from google.shopping.merchant_datasources_v1beta.services.data_sources_service import ( @@ -591,6 +601,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( @@ -657,6 +671,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.shopping.merchant.datasources_v1beta.DataSourcesServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.datasources.v1beta.DataSourcesService", + "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.shopping.merchant.datasources.v1beta.DataSourcesService", + "credentialsType": None, + }, + ) + def get_data_source( self, request: Optional[Union[datasources.GetDataSourceRequest, dict]] = None, @@ -664,7 +701,7 @@ def get_data_source( 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]]] = (), ) -> datasources.DataSource: r"""Retrieves the data source configuration for the given account. @@ -709,8 +746,10 @@ def sample_get_data_source(): 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.shopping.merchant_datasources_v1beta.types.DataSource: @@ -768,7 +807,7 @@ def list_data_sources( 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.ListDataSourcesPager: r"""Lists the configurations for data sources for the given account. @@ -814,8 +853,10 @@ def sample_list_data_sources(): 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.shopping.merchant_datasources_v1beta.services.data_sources_service.pagers.ListDataSourcesPager: @@ -888,7 +929,7 @@ def create_data_source( data_source: Optional[datasources.DataSource] = 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]]] = (), ) -> datasources.DataSource: r"""Creates the new data source configuration for the given account. @@ -943,8 +984,10 @@ def sample_create_data_source(): 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.shopping.merchant_datasources_v1beta.types.DataSource: @@ -1005,7 +1048,7 @@ def update_data_source( 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]]] = (), ) -> datasources.DataSource: r"""Updates the existing data source configuration. The fields that are set in the update mask but not provided @@ -1068,8 +1111,10 @@ def sample_update_data_source(): 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.shopping.merchant_datasources_v1beta.types.DataSource: @@ -1131,7 +1176,7 @@ def delete_data_source( 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 data source from your Merchant Center account. @@ -1173,8 +1218,10 @@ def sample_delete_data_source(): 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 @@ -1222,7 +1269,7 @@ def fetch_data_source( *, 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"""Performs the data fetch immediately (even outside fetch schedule) on a data source from your Merchant @@ -1262,8 +1309,10 @@ def sample_fetch_data_source(): 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. # - Use the request object if provided (there's no risk of modifying the input as diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/pagers.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/pagers.py index 1f983ce9a916..f368c1829f65 100644 --- a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/pagers.py +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/pagers.py @@ -67,7 +67,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. @@ -81,8 +81,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 = datasources.ListDataSourcesRequest(request) @@ -141,7 +143,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. @@ -155,8 +157,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 = datasources.ListDataSourcesRequest(request) diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/grpc.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/grpc.py index e944ad0bfa64..c204d470bbf3 100644 --- a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/grpc.py +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -21,12 +24,90 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore +import proto # type: ignore from google.shopping.merchant_datasources_v1beta.types import datasources from .base import DEFAULT_CLIENT_INFO, DataSourcesServiceTransport +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.shopping.merchant.datasources.v1beta.DataSourcesService", + "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.shopping.merchant.datasources.v1beta.DataSourcesService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class DataSourcesServiceGrpcTransport(DataSourcesServiceTransport): """gRPC backend transport for DataSourcesService. @@ -183,7 +264,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 @@ -258,7 +344,7 @@ def get_data_source( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_data_source" not in self._stubs: - self._stubs["get_data_source"] = self.grpc_channel.unary_unary( + self._stubs["get_data_source"] = self._logged_channel.unary_unary( "/google.shopping.merchant.datasources.v1beta.DataSourcesService/GetDataSource", request_serializer=datasources.GetDataSourceRequest.serialize, response_deserializer=datasources.DataSource.deserialize, @@ -287,7 +373,7 @@ def list_data_sources( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_data_sources" not in self._stubs: - self._stubs["list_data_sources"] = self.grpc_channel.unary_unary( + self._stubs["list_data_sources"] = self._logged_channel.unary_unary( "/google.shopping.merchant.datasources.v1beta.DataSourcesService/ListDataSources", request_serializer=datasources.ListDataSourcesRequest.serialize, response_deserializer=datasources.ListDataSourcesResponse.deserialize, @@ -314,7 +400,7 @@ def create_data_source( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_data_source" not in self._stubs: - self._stubs["create_data_source"] = self.grpc_channel.unary_unary( + self._stubs["create_data_source"] = self._logged_channel.unary_unary( "/google.shopping.merchant.datasources.v1beta.DataSourcesService/CreateDataSource", request_serializer=datasources.CreateDataSourceRequest.serialize, response_deserializer=datasources.DataSource.deserialize, @@ -342,7 +428,7 @@ def update_data_source( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_data_source" not in self._stubs: - self._stubs["update_data_source"] = self.grpc_channel.unary_unary( + self._stubs["update_data_source"] = self._logged_channel.unary_unary( "/google.shopping.merchant.datasources.v1beta.DataSourcesService/UpdateDataSource", request_serializer=datasources.UpdateDataSourceRequest.serialize, response_deserializer=datasources.DataSource.deserialize, @@ -369,7 +455,7 @@ def delete_data_source( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_data_source" not in self._stubs: - self._stubs["delete_data_source"] = self.grpc_channel.unary_unary( + self._stubs["delete_data_source"] = self._logged_channel.unary_unary( "/google.shopping.merchant.datasources.v1beta.DataSourcesService/DeleteDataSource", request_serializer=datasources.DeleteDataSourceRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -401,7 +487,7 @@ def fetch_data_source( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "fetch_data_source" not in self._stubs: - self._stubs["fetch_data_source"] = self.grpc_channel.unary_unary( + self._stubs["fetch_data_source"] = self._logged_channel.unary_unary( "/google.shopping.merchant.datasources.v1beta.DataSourcesService/FetchDataSource", request_serializer=datasources.FetchDataSourceRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -409,7 +495,7 @@ def fetch_data_source( return self._stubs["fetch_data_source"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/grpc_asyncio.py index 77dcf8525878..958181bd7a14 100644 --- a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -23,14 +26,93 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_datasources_v1beta.types import datasources from .base import DEFAULT_CLIENT_INFO, DataSourcesServiceTransport from .grpc import DataSourcesServiceGrpcTransport +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.shopping.merchant.datasources.v1beta.DataSourcesService", + "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.shopping.merchant.datasources.v1beta.DataSourcesService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class DataSourcesServiceGrpcAsyncIOTransport(DataSourcesServiceTransport): """gRPC AsyncIO backend transport for DataSourcesService. @@ -230,10 +312,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 get_data_source( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_data_source" not in self._stubs: - self._stubs["get_data_source"] = self.grpc_channel.unary_unary( + self._stubs["get_data_source"] = self._logged_channel.unary_unary( "/google.shopping.merchant.datasources.v1beta.DataSourcesService/GetDataSource", request_serializer=datasources.GetDataSourceRequest.serialize, response_deserializer=datasources.DataSource.deserialize, @@ -298,7 +383,7 @@ def list_data_sources( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_data_sources" not in self._stubs: - self._stubs["list_data_sources"] = self.grpc_channel.unary_unary( + self._stubs["list_data_sources"] = self._logged_channel.unary_unary( "/google.shopping.merchant.datasources.v1beta.DataSourcesService/ListDataSources", request_serializer=datasources.ListDataSourcesRequest.serialize, response_deserializer=datasources.ListDataSourcesResponse.deserialize, @@ -327,7 +412,7 @@ def create_data_source( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_data_source" not in self._stubs: - self._stubs["create_data_source"] = self.grpc_channel.unary_unary( + self._stubs["create_data_source"] = self._logged_channel.unary_unary( "/google.shopping.merchant.datasources.v1beta.DataSourcesService/CreateDataSource", request_serializer=datasources.CreateDataSourceRequest.serialize, response_deserializer=datasources.DataSource.deserialize, @@ -357,7 +442,7 @@ def update_data_source( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_data_source" not in self._stubs: - self._stubs["update_data_source"] = self.grpc_channel.unary_unary( + self._stubs["update_data_source"] = self._logged_channel.unary_unary( "/google.shopping.merchant.datasources.v1beta.DataSourcesService/UpdateDataSource", request_serializer=datasources.UpdateDataSourceRequest.serialize, response_deserializer=datasources.DataSource.deserialize, @@ -384,7 +469,7 @@ def delete_data_source( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_data_source" not in self._stubs: - self._stubs["delete_data_source"] = self.grpc_channel.unary_unary( + self._stubs["delete_data_source"] = self._logged_channel.unary_unary( "/google.shopping.merchant.datasources.v1beta.DataSourcesService/DeleteDataSource", request_serializer=datasources.DeleteDataSourceRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -416,7 +501,7 @@ def fetch_data_source( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "fetch_data_source" not in self._stubs: - self._stubs["fetch_data_source"] = self.grpc_channel.unary_unary( + self._stubs["fetch_data_source"] = self._logged_channel.unary_unary( "/google.shopping.merchant.datasources.v1beta.DataSourcesService/FetchDataSource", request_serializer=datasources.FetchDataSourceRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -464,7 +549,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/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/rest.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/rest.py index e864db17089a..b523758bc8fb 100644 --- a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/rest.py +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -38,6 +38,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, @@ -110,8 +118,10 @@ def post_update_data_source(self, response): def pre_create_data_source( self, request: datasources.CreateDataSourceRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[datasources.CreateDataSourceRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datasources.CreateDataSourceRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for create_data_source Override in a subclass to manipulate the request or metadata @@ -133,8 +143,10 @@ def post_create_data_source( def pre_delete_data_source( self, request: datasources.DeleteDataSourceRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[datasources.DeleteDataSourceRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datasources.DeleteDataSourceRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for delete_data_source Override in a subclass to manipulate the request or metadata @@ -145,8 +157,10 @@ def pre_delete_data_source( def pre_fetch_data_source( self, request: datasources.FetchDataSourceRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[datasources.FetchDataSourceRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datasources.FetchDataSourceRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for fetch_data_source Override in a subclass to manipulate the request or metadata @@ -157,8 +171,10 @@ def pre_fetch_data_source( def pre_get_data_source( self, request: datasources.GetDataSourceRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[datasources.GetDataSourceRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datasources.GetDataSourceRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for get_data_source Override in a subclass to manipulate the request or metadata @@ -180,8 +196,10 @@ def post_get_data_source( def pre_list_data_sources( self, request: datasources.ListDataSourcesRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[datasources.ListDataSourcesRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datasources.ListDataSourcesRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for list_data_sources Override in a subclass to manipulate the request or metadata @@ -203,8 +221,10 @@ def post_list_data_sources( def pre_update_data_source( self, request: datasources.UpdateDataSourceRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[datasources.UpdateDataSourceRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datasources.UpdateDataSourceRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for update_data_source Override in a subclass to manipulate the request or metadata @@ -349,7 +369,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]]] = (), ) -> datasources.DataSource: r"""Call the create data source method over HTTP. @@ -360,8 +380,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: ~.datasources.DataSource: @@ -374,6 +396,7 @@ def __call__( http_options = ( _BaseDataSourcesServiceRestTransport._BaseCreateDataSource._get_http_options() ) + request, metadata = self._interceptor.pre_create_data_source( request, metadata ) @@ -390,6 +413,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.shopping.merchant.datasources_v1beta.DataSourcesServiceClient.CreateDataSource", + extra={ + "serviceName": "google.shopping.merchant.datasources.v1beta.DataSourcesService", + "rpcName": "CreateDataSource", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = DataSourcesServiceRestTransport._CreateDataSource._get_response( self._host, @@ -411,7 +461,29 @@ def __call__( pb_resp = datasources.DataSource.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_data_source(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = datasources.DataSource.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.shopping.merchant.datasources_v1beta.DataSourcesServiceClient.create_data_source", + extra={ + "serviceName": "google.shopping.merchant.datasources.v1beta.DataSourcesService", + "rpcName": "CreateDataSource", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _DeleteDataSource( @@ -449,7 +521,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 data source method over HTTP. @@ -460,13 +532,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 = ( _BaseDataSourcesServiceRestTransport._BaseDeleteDataSource._get_http_options() ) + request, metadata = self._interceptor.pre_delete_data_source( request, metadata ) @@ -479,6 +554,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.shopping.merchant.datasources_v1beta.DataSourcesServiceClient.DeleteDataSource", + extra={ + "serviceName": "google.shopping.merchant.datasources.v1beta.DataSourcesService", + "rpcName": "DeleteDataSource", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = DataSourcesServiceRestTransport._DeleteDataSource._get_response( self._host, @@ -530,7 +632,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 fetch data source method over HTTP. @@ -541,13 +643,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 = ( _BaseDataSourcesServiceRestTransport._BaseFetchDataSource._get_http_options() ) + request, metadata = self._interceptor.pre_fetch_data_source( request, metadata ) @@ -564,6 +669,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.shopping.merchant.datasources_v1beta.DataSourcesServiceClient.FetchDataSource", + extra={ + "serviceName": "google.shopping.merchant.datasources.v1beta.DataSourcesService", + "rpcName": "FetchDataSource", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = DataSourcesServiceRestTransport._FetchDataSource._get_response( self._host, @@ -615,7 +747,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]]] = (), ) -> datasources.DataSource: r"""Call the get data source method over HTTP. @@ -626,8 +758,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: ~.datasources.DataSource: @@ -640,6 +774,7 @@ def __call__( http_options = ( _BaseDataSourcesServiceRestTransport._BaseGetDataSource._get_http_options() ) + request, metadata = self._interceptor.pre_get_data_source(request, metadata) transcoded_request = _BaseDataSourcesServiceRestTransport._BaseGetDataSource._get_transcoded_request( http_options, request @@ -650,6 +785,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.shopping.merchant.datasources_v1beta.DataSourcesServiceClient.GetDataSource", + extra={ + "serviceName": "google.shopping.merchant.datasources.v1beta.DataSourcesService", + "rpcName": "GetDataSource", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = DataSourcesServiceRestTransport._GetDataSource._get_response( self._host, @@ -670,7 +832,29 @@ def __call__( pb_resp = datasources.DataSource.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_data_source(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = datasources.DataSource.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.shopping.merchant.datasources_v1beta.DataSourcesServiceClient.get_data_source", + extra={ + "serviceName": "google.shopping.merchant.datasources.v1beta.DataSourcesService", + "rpcName": "GetDataSource", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListDataSources( @@ -708,7 +892,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]]] = (), ) -> datasources.ListDataSourcesResponse: r"""Call the list data sources method over HTTP. @@ -719,8 +903,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: ~.datasources.ListDataSourcesResponse: @@ -732,6 +918,7 @@ def __call__( http_options = ( _BaseDataSourcesServiceRestTransport._BaseListDataSources._get_http_options() ) + request, metadata = self._interceptor.pre_list_data_sources( request, metadata ) @@ -744,6 +931,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.shopping.merchant.datasources_v1beta.DataSourcesServiceClient.ListDataSources", + extra={ + "serviceName": "google.shopping.merchant.datasources.v1beta.DataSourcesService", + "rpcName": "ListDataSources", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = DataSourcesServiceRestTransport._ListDataSources._get_response( self._host, @@ -764,7 +978,31 @@ def __call__( pb_resp = datasources.ListDataSourcesResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_data_sources(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = datasources.ListDataSourcesResponse.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.shopping.merchant.datasources_v1beta.DataSourcesServiceClient.list_data_sources", + extra={ + "serviceName": "google.shopping.merchant.datasources.v1beta.DataSourcesService", + "rpcName": "ListDataSources", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _UpdateDataSource( @@ -803,7 +1041,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]]] = (), ) -> datasources.DataSource: r"""Call the update data source method over HTTP. @@ -814,8 +1052,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: ~.datasources.DataSource: @@ -828,6 +1068,7 @@ def __call__( http_options = ( _BaseDataSourcesServiceRestTransport._BaseUpdateDataSource._get_http_options() ) + request, metadata = self._interceptor.pre_update_data_source( request, metadata ) @@ -844,6 +1085,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.shopping.merchant.datasources_v1beta.DataSourcesServiceClient.UpdateDataSource", + extra={ + "serviceName": "google.shopping.merchant.datasources.v1beta.DataSourcesService", + "rpcName": "UpdateDataSource", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = DataSourcesServiceRestTransport._UpdateDataSource._get_response( self._host, @@ -865,7 +1133,29 @@ def __call__( pb_resp = datasources.DataSource.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_data_source(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = datasources.DataSource.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.shopping.merchant.datasources_v1beta.DataSourcesServiceClient.update_data_source", + extra={ + "serviceName": "google.shopping.merchant.datasources.v1beta.DataSourcesService", + "rpcName": "UpdateDataSource", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/async_client.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/async_client.py index 909683366907..bc468c249336 100644 --- a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/async_client.py +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -50,6 +51,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, FileUploadsServiceTransport from .transports.grpc_asyncio import FileUploadsServiceGrpcAsyncIOTransport +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 FileUploadsServiceAsyncClient: """Service to manage data source file uploads.""" @@ -261,6 +271,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.shopping.merchant.datasources_v1beta.FileUploadsServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.datasources.v1beta.FileUploadsService", + "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.shopping.merchant.datasources.v1beta.FileUploadsService", + "credentialsType": None, + }, + ) + async def get_file_upload( self, request: Optional[Union[fileuploads.GetFileUploadRequest, dict]] = None, @@ -268,7 +300,7 @@ async def get_file_upload( 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]]] = (), ) -> fileuploads.FileUpload: r"""Gets the latest data source file upload. Only the ``latest`` alias is accepted for a file upload. @@ -314,8 +346,10 @@ async def sample_get_file_upload(): 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.shopping.merchant_datasources_v1beta.types.FileUpload: diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/client.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/client.py index 58989eaff667..370ed30093ca 100644 --- a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/client.py +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.protobuf import timestamp_pb2 # type: ignore from google.shopping.merchant_datasources_v1beta.types import fileuploads @@ -583,6 +593,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( @@ -649,6 +663,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.shopping.merchant.datasources_v1beta.FileUploadsServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.datasources.v1beta.FileUploadsService", + "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.shopping.merchant.datasources.v1beta.FileUploadsService", + "credentialsType": None, + }, + ) + def get_file_upload( self, request: Optional[Union[fileuploads.GetFileUploadRequest, dict]] = None, @@ -656,7 +693,7 @@ def get_file_upload( 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]]] = (), ) -> fileuploads.FileUpload: r"""Gets the latest data source file upload. Only the ``latest`` alias is accepted for a file upload. @@ -702,8 +739,10 @@ def sample_get_file_upload(): 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.shopping.merchant_datasources_v1beta.types.FileUpload: diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/grpc.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/grpc.py index 7bbea5efafca..acb6bef134d5 100644 --- a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/grpc.py +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -20,12 +23,90 @@ 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.shopping.merchant_datasources_v1beta.types import fileuploads from .base import DEFAULT_CLIENT_INFO, FileUploadsServiceTransport +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.shopping.merchant.datasources.v1beta.FileUploadsService", + "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.shopping.merchant.datasources.v1beta.FileUploadsService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class FileUploadsServiceGrpcTransport(FileUploadsServiceTransport): """gRPC backend transport for FileUploadsService. @@ -179,7 +260,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 @@ -254,7 +340,7 @@ def get_file_upload( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_file_upload" not in self._stubs: - self._stubs["get_file_upload"] = self.grpc_channel.unary_unary( + self._stubs["get_file_upload"] = self._logged_channel.unary_unary( "/google.shopping.merchant.datasources.v1beta.FileUploadsService/GetFileUpload", request_serializer=fileuploads.GetFileUploadRequest.serialize, response_deserializer=fileuploads.FileUpload.deserialize, @@ -262,7 +348,7 @@ def get_file_upload( return self._stubs["get_file_upload"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/grpc_asyncio.py index 5ef15b13b560..dd64312f7a48 100644 --- a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -22,14 +25,93 @@ 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 from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_datasources_v1beta.types import fileuploads from .base import DEFAULT_CLIENT_INFO, FileUploadsServiceTransport from .grpc import FileUploadsServiceGrpcTransport +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.shopping.merchant.datasources.v1beta.FileUploadsService", + "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.shopping.merchant.datasources.v1beta.FileUploadsService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class FileUploadsServiceGrpcAsyncIOTransport(FileUploadsServiceTransport): """gRPC AsyncIO backend transport for FileUploadsService. @@ -226,10 +308,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 @@ -264,7 +349,7 @@ def get_file_upload( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_file_upload" not in self._stubs: - self._stubs["get_file_upload"] = self.grpc_channel.unary_unary( + self._stubs["get_file_upload"] = self._logged_channel.unary_unary( "/google.shopping.merchant.datasources.v1beta.FileUploadsService/GetFileUpload", request_serializer=fileuploads.GetFileUploadRequest.serialize, response_deserializer=fileuploads.FileUpload.deserialize, @@ -287,7 +372,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/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/rest.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/rest.py index e54b65f178a1..2619a225f56a 100644 --- a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/rest.py +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -37,6 +37,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, @@ -77,8 +85,10 @@ def post_get_file_upload(self, response): def pre_get_file_upload( self, request: fileuploads.GetFileUploadRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[fileuploads.GetFileUploadRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + fileuploads.GetFileUploadRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for get_file_upload Override in a subclass to manipulate the request or metadata @@ -219,7 +229,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]]] = (), ) -> fileuploads.FileUpload: r"""Call the get file upload method over HTTP. @@ -230,8 +240,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: ~.fileuploads.FileUpload: @@ -248,6 +260,7 @@ def __call__( http_options = ( _BaseFileUploadsServiceRestTransport._BaseGetFileUpload._get_http_options() ) + request, metadata = self._interceptor.pre_get_file_upload(request, metadata) transcoded_request = _BaseFileUploadsServiceRestTransport._BaseGetFileUpload._get_transcoded_request( http_options, request @@ -258,6 +271,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.shopping.merchant.datasources_v1beta.FileUploadsServiceClient.GetFileUpload", + extra={ + "serviceName": "google.shopping.merchant.datasources.v1beta.FileUploadsService", + "rpcName": "GetFileUpload", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = FileUploadsServiceRestTransport._GetFileUpload._get_response( self._host, @@ -278,7 +318,29 @@ def __call__( pb_resp = fileuploads.FileUpload.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_file_upload(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = fileuploads.FileUpload.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.shopping.merchant.datasources_v1beta.FileUploadsServiceClient.get_file_upload", + extra={ + "serviceName": "google.shopping.merchant.datasources.v1beta.FileUploadsService", + "rpcName": "GetFileUpload", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-datasources/samples/generated_samples/snippet_metadata_google.shopping.merchant.datasources.v1beta.json b/packages/google-shopping-merchant-datasources/samples/generated_samples/snippet_metadata_google.shopping.merchant.datasources.v1beta.json index bc99eab63257..992de0dc6fb0 100644 --- a/packages/google-shopping-merchant-datasources/samples/generated_samples/snippet_metadata_google.shopping.merchant.datasources.v1beta.json +++ b/packages/google-shopping-merchant-datasources/samples/generated_samples/snippet_metadata_google.shopping.merchant.datasources.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-shopping-merchant-datasources", - "version": "0.1.5" + "version": "0.1.0" }, "snippets": [ { @@ -51,7 +51,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_datasources_v1beta.types.DataSource", @@ -135,7 +135,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_datasources_v1beta.types.DataSource", @@ -216,7 +216,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_data_source" @@ -293,7 +293,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_data_source" @@ -367,7 +367,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "fetch_data_source" @@ -440,7 +440,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "fetch_data_source" @@ -518,7 +518,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_datasources_v1beta.types.DataSource", @@ -598,7 +598,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_datasources_v1beta.types.DataSource", @@ -679,7 +679,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_datasources_v1beta.services.data_sources_service.pagers.ListDataSourcesAsyncPager", @@ -759,7 +759,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_datasources_v1beta.services.data_sources_service.pagers.ListDataSourcesPager", @@ -844,7 +844,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_datasources_v1beta.types.DataSource", @@ -928,7 +928,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_datasources_v1beta.types.DataSource", @@ -1009,7 +1009,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_datasources_v1beta.types.FileUpload", @@ -1089,7 +1089,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_datasources_v1beta.types.FileUpload", diff --git a/packages/google-shopping-merchant-datasources/tests/unit/gapic/merchant_datasources_v1beta/test_data_sources_service.py b/packages/google-shopping-merchant-datasources/tests/unit/gapic/merchant_datasources_v1beta/test_data_sources_service.py index a736f6e241c0..a91284b58312 100644 --- a/packages/google-shopping-merchant-datasources/tests/unit/gapic/merchant_datasources_v1beta/test_data_sources_service.py +++ b/packages/google-shopping-merchant-datasources/tests/unit/gapic/merchant_datasources_v1beta/test_data_sources_service.py @@ -3431,6 +3431,7 @@ def test_get_data_source_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_data_source(request) @@ -3476,6 +3477,7 @@ def test_get_data_source_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_data_source(**mock_args) @@ -3616,6 +3618,7 @@ def test_list_data_sources_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_data_sources(request) @@ -3669,6 +3672,7 @@ def test_list_data_sources_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_data_sources(**mock_args) @@ -3868,6 +3872,7 @@ def test_create_data_source_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_data_source(request) @@ -3926,6 +3931,7 @@ def test_create_data_source_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_data_source(**mock_args) @@ -4064,6 +4070,7 @@ def test_update_data_source_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_data_source(request) @@ -4124,6 +4131,7 @@ def test_update_data_source_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_data_source(**mock_args) @@ -4261,6 +4269,7 @@ def test_delete_data_source_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_data_source(request) @@ -4304,6 +4313,7 @@ def test_delete_data_source_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_data_source(**mock_args) @@ -4435,6 +4445,7 @@ def test_fetch_data_source_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.fetch_data_source(request) @@ -4909,6 +4920,7 @@ def test_get_data_source_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.get_data_source(request) @@ -4947,6 +4959,7 @@ def test_get_data_source_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_data_source(request) # Establish that the response is the type that we expect. @@ -4990,6 +5003,7 @@ def test_get_data_source_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 = datasources.DataSource.to_json(datasources.DataSource()) req.return_value.content = return_value @@ -5034,6 +5048,7 @@ def test_list_data_sources_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_data_sources(request) @@ -5069,6 +5084,7 @@ def test_list_data_sources_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_data_sources(request) # Establish that the response is the type that we expect. @@ -5109,6 +5125,7 @@ def test_list_data_sources_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 = datasources.ListDataSourcesResponse.to_json( datasources.ListDataSourcesResponse() ) @@ -5155,6 +5172,7 @@ def test_create_data_source_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.create_data_source(request) @@ -5318,6 +5336,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_data_source(request) # Establish that the response is the type that we expect. @@ -5361,6 +5380,7 @@ def test_create_data_source_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 = datasources.DataSource.to_json(datasources.DataSource()) req.return_value.content = return_value @@ -5405,6 +5425,7 @@ def test_update_data_source_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_data_source(request) @@ -5568,6 +5589,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.update_data_source(request) # Establish that the response is the type that we expect. @@ -5611,6 +5633,7 @@ def test_update_data_source_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 = datasources.DataSource.to_json(datasources.DataSource()) req.return_value.content = return_value @@ -5655,6 +5678,7 @@ def test_delete_data_source_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_data_source(request) @@ -5685,6 +5709,7 @@ def test_delete_data_source_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_data_source(request) # Establish that the response is the type that we expect. @@ -5721,6 +5746,7 @@ def test_delete_data_source_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 = datasources.DeleteDataSourceRequest() metadata = [ @@ -5761,6 +5787,7 @@ def test_fetch_data_source_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.fetch_data_source(request) @@ -5791,6 +5818,7 @@ def test_fetch_data_source_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.fetch_data_source(request) # Establish that the response is the type that we expect. @@ -5827,6 +5855,7 @@ def test_fetch_data_source_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 = datasources.FetchDataSourceRequest() metadata = [ diff --git a/packages/google-shopping-merchant-datasources/tests/unit/gapic/merchant_datasources_v1beta/test_file_uploads_service.py b/packages/google-shopping-merchant-datasources/tests/unit/gapic/merchant_datasources_v1beta/test_file_uploads_service.py index 30b7da6ff9dd..1d9ea6845d70 100644 --- a/packages/google-shopping-merchant-datasources/tests/unit/gapic/merchant_datasources_v1beta/test_file_uploads_service.py +++ b/packages/google-shopping-merchant-datasources/tests/unit/gapic/merchant_datasources_v1beta/test_file_uploads_service.py @@ -1547,6 +1547,7 @@ def test_get_file_upload_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_file_upload(request) @@ -1594,6 +1595,7 @@ def test_get_file_upload_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_file_upload(**mock_args) @@ -1824,6 +1826,7 @@ def test_get_file_upload_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.get_file_upload(request) @@ -1864,6 +1867,7 @@ def test_get_file_upload_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_file_upload(request) # Establish that the response is the type that we expect. @@ -1909,6 +1913,7 @@ def test_get_file_upload_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 = fileuploads.FileUpload.to_json(fileuploads.FileUpload()) req.return_value.content = return_value diff --git a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories/gapic_version.py b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories/gapic_version.py index 4b834789ba9e..558c8aab67c5 100644 --- a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories/gapic_version.py +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.11" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/gapic_version.py b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/gapic_version.py index 4b834789ba9e..558c8aab67c5 100644 --- a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/gapic_version.py +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.11" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/async_client.py b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/async_client.py index 5aee1badcfa4..5a47dd695a65 100644 --- a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/async_client.py +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -54,6 +55,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, LocalInventoryServiceTransport from .transports.grpc_asyncio import LocalInventoryServiceGrpcAsyncIOTransport +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 LocalInventoryServiceAsyncClient: """Service to manage local inventory for products""" @@ -269,6 +279,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.shopping.merchant.inventories_v1beta.LocalInventoryServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.inventories.v1beta.LocalInventoryService", + "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.shopping.merchant.inventories.v1beta.LocalInventoryService", + "credentialsType": None, + }, + ) + async def list_local_inventories( self, request: Optional[ @@ -278,7 +310,7 @@ async def list_local_inventories( 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.ListLocalInventoriesAsyncPager: r"""Lists the ``LocalInventory`` resources for the given product in your merchant account. The response might contain fewer items @@ -329,8 +361,10 @@ async def sample_list_local_inventories(): 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.shopping.merchant_inventories_v1beta.services.local_inventory_service.pagers.ListLocalInventoriesAsyncPager: @@ -405,7 +439,7 @@ async def insert_local_inventory( *, 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]]] = (), ) -> localinventory.LocalInventory: r"""Inserts a ``LocalInventory`` resource to a product in your merchant account. @@ -454,8 +488,10 @@ async def sample_insert_local_inventory(): 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.shopping.merchant_inventories_v1beta.types.LocalInventory: @@ -508,7 +544,7 @@ async def delete_local_inventory( 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 the specified ``LocalInventory`` from the given product in your merchant account. It might take a up to an hour for the @@ -553,8 +589,10 @@ async def sample_delete_local_inventory(): 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 diff --git a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/client.py b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/client.py index 21e8370f3816..29fa40212482 100644 --- a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/client.py +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.shopping.type.types import types from google.type import interval_pb2 # type: ignore @@ -589,6 +599,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( @@ -655,6 +669,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.shopping.merchant.inventories_v1beta.LocalInventoryServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.inventories.v1beta.LocalInventoryService", + "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.shopping.merchant.inventories.v1beta.LocalInventoryService", + "credentialsType": None, + }, + ) + def list_local_inventories( self, request: Optional[ @@ -664,7 +701,7 @@ def list_local_inventories( 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.ListLocalInventoriesPager: r"""Lists the ``LocalInventory`` resources for the given product in your merchant account. The response might contain fewer items @@ -715,8 +752,10 @@ def sample_list_local_inventories(): 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.shopping.merchant_inventories_v1beta.services.local_inventory_service.pagers.ListLocalInventoriesPager: @@ -788,7 +827,7 @@ def insert_local_inventory( *, 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]]] = (), ) -> localinventory.LocalInventory: r"""Inserts a ``LocalInventory`` resource to a product in your merchant account. @@ -837,8 +876,10 @@ def sample_insert_local_inventory(): 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.shopping.merchant_inventories_v1beta.types.LocalInventory: @@ -889,7 +930,7 @@ def delete_local_inventory( 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 the specified ``LocalInventory`` from the given product in your merchant account. It might take a up to an hour for the @@ -934,8 +975,10 @@ def sample_delete_local_inventory(): 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 diff --git a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/pagers.py b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/pagers.py index f406baae6275..ab034e14e8bd 100644 --- a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/pagers.py +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/pagers.py @@ -67,7 +67,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. @@ -81,8 +81,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 = localinventory.ListLocalInventoriesRequest(request) @@ -141,7 +143,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. @@ -155,8 +157,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 = localinventory.ListLocalInventoriesRequest(request) diff --git a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/grpc.py b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/grpc.py index 1a0d7e9d3bf7..e9f818913484 100644 --- a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/grpc.py +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -21,12 +24,90 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore +import proto # type: ignore from google.shopping.merchant_inventories_v1beta.types import localinventory from .base import DEFAULT_CLIENT_INFO, LocalInventoryServiceTransport +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.shopping.merchant.inventories.v1beta.LocalInventoryService", + "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.shopping.merchant.inventories.v1beta.LocalInventoryService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class LocalInventoryServiceGrpcTransport(LocalInventoryServiceTransport): """gRPC backend transport for LocalInventoryService. @@ -180,7 +261,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 @@ -263,7 +349,7 @@ def list_local_inventories( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_local_inventories" not in self._stubs: - self._stubs["list_local_inventories"] = self.grpc_channel.unary_unary( + self._stubs["list_local_inventories"] = self._logged_channel.unary_unary( "/google.shopping.merchant.inventories.v1beta.LocalInventoryService/ListLocalInventories", request_serializer=localinventory.ListLocalInventoriesRequest.serialize, response_deserializer=localinventory.ListLocalInventoriesResponse.deserialize, @@ -300,7 +386,7 @@ def insert_local_inventory( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "insert_local_inventory" not in self._stubs: - self._stubs["insert_local_inventory"] = self.grpc_channel.unary_unary( + self._stubs["insert_local_inventory"] = self._logged_channel.unary_unary( "/google.shopping.merchant.inventories.v1beta.LocalInventoryService/InsertLocalInventory", request_serializer=localinventory.InsertLocalInventoryRequest.serialize, response_deserializer=localinventory.LocalInventory.deserialize, @@ -330,7 +416,7 @@ def delete_local_inventory( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_local_inventory" not in self._stubs: - self._stubs["delete_local_inventory"] = self.grpc_channel.unary_unary( + self._stubs["delete_local_inventory"] = self._logged_channel.unary_unary( "/google.shopping.merchant.inventories.v1beta.LocalInventoryService/DeleteLocalInventory", request_serializer=localinventory.DeleteLocalInventoryRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -338,7 +424,7 @@ def delete_local_inventory( return self._stubs["delete_local_inventory"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/grpc_asyncio.py index 8a71b2ecadb1..7b73b7edebb5 100644 --- a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -23,14 +26,93 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_inventories_v1beta.types import localinventory from .base import DEFAULT_CLIENT_INFO, LocalInventoryServiceTransport from .grpc import LocalInventoryServiceGrpcTransport +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.shopping.merchant.inventories.v1beta.LocalInventoryService", + "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.shopping.merchant.inventories.v1beta.LocalInventoryService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class LocalInventoryServiceGrpcAsyncIOTransport(LocalInventoryServiceTransport): """gRPC AsyncIO backend transport for LocalInventoryService. @@ -227,10 +309,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 @@ -271,7 +356,7 @@ def list_local_inventories( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_local_inventories" not in self._stubs: - self._stubs["list_local_inventories"] = self.grpc_channel.unary_unary( + self._stubs["list_local_inventories"] = self._logged_channel.unary_unary( "/google.shopping.merchant.inventories.v1beta.LocalInventoryService/ListLocalInventories", request_serializer=localinventory.ListLocalInventoriesRequest.serialize, response_deserializer=localinventory.ListLocalInventoriesResponse.deserialize, @@ -309,7 +394,7 @@ def insert_local_inventory( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "insert_local_inventory" not in self._stubs: - self._stubs["insert_local_inventory"] = self.grpc_channel.unary_unary( + self._stubs["insert_local_inventory"] = self._logged_channel.unary_unary( "/google.shopping.merchant.inventories.v1beta.LocalInventoryService/InsertLocalInventory", request_serializer=localinventory.InsertLocalInventoryRequest.serialize, response_deserializer=localinventory.LocalInventory.deserialize, @@ -341,7 +426,7 @@ def delete_local_inventory( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_local_inventory" not in self._stubs: - self._stubs["delete_local_inventory"] = self.grpc_channel.unary_unary( + self._stubs["delete_local_inventory"] = self._logged_channel.unary_unary( "/google.shopping.merchant.inventories.v1beta.LocalInventoryService/DeleteLocalInventory", request_serializer=localinventory.DeleteLocalInventoryRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -374,7 +459,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/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/rest.py b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/rest.py index ec939a04a0c4..30a453c86e38 100644 --- a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/rest.py +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -38,6 +38,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, @@ -90,8 +98,11 @@ def post_list_local_inventories(self, response): def pre_delete_local_inventory( self, request: localinventory.DeleteLocalInventoryRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[localinventory.DeleteLocalInventoryRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + localinventory.DeleteLocalInventoryRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: """Pre-rpc interceptor for delete_local_inventory Override in a subclass to manipulate the request or metadata @@ -102,8 +113,11 @@ def pre_delete_local_inventory( def pre_insert_local_inventory( self, request: localinventory.InsertLocalInventoryRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[localinventory.InsertLocalInventoryRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + localinventory.InsertLocalInventoryRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: """Pre-rpc interceptor for insert_local_inventory Override in a subclass to manipulate the request or metadata @@ -125,8 +139,11 @@ def post_insert_local_inventory( def pre_list_local_inventories( self, request: localinventory.ListLocalInventoriesRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[localinventory.ListLocalInventoriesRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + localinventory.ListLocalInventoriesRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: """Pre-rpc interceptor for list_local_inventories Override in a subclass to manipulate the request or metadata @@ -267,7 +284,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 local inventory method over HTTP. @@ -277,13 +294,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 = ( _BaseLocalInventoryServiceRestTransport._BaseDeleteLocalInventory._get_http_options() ) + request, metadata = self._interceptor.pre_delete_local_inventory( request, metadata ) @@ -296,6 +316,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.shopping.merchant.inventories_v1beta.LocalInventoryServiceClient.DeleteLocalInventory", + extra={ + "serviceName": "google.shopping.merchant.inventories.v1beta.LocalInventoryService", + "rpcName": "DeleteLocalInventory", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ( LocalInventoryServiceRestTransport._DeleteLocalInventory._get_response( @@ -349,7 +396,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]]] = (), ) -> localinventory.LocalInventory: r"""Call the insert local inventory method over HTTP. @@ -359,8 +406,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: ~.localinventory.LocalInventory: @@ -377,6 +426,7 @@ def __call__( http_options = ( _BaseLocalInventoryServiceRestTransport._BaseInsertLocalInventory._get_http_options() ) + request, metadata = self._interceptor.pre_insert_local_inventory( request, metadata ) @@ -393,6 +443,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.shopping.merchant.inventories_v1beta.LocalInventoryServiceClient.InsertLocalInventory", + extra={ + "serviceName": "google.shopping.merchant.inventories.v1beta.LocalInventoryService", + "rpcName": "InsertLocalInventory", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ( LocalInventoryServiceRestTransport._InsertLocalInventory._get_response( @@ -416,7 +493,29 @@ def __call__( pb_resp = localinventory.LocalInventory.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_insert_local_inventory(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = localinventory.LocalInventory.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.shopping.merchant.inventories_v1beta.LocalInventoryServiceClient.insert_local_inventory", + extra={ + "serviceName": "google.shopping.merchant.inventories.v1beta.LocalInventoryService", + "rpcName": "InsertLocalInventory", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListLocalInventories( @@ -454,7 +553,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]]] = (), ) -> localinventory.ListLocalInventoriesResponse: r"""Call the list local inventories method over HTTP. @@ -464,8 +563,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: ~.localinventory.ListLocalInventoriesResponse: @@ -477,6 +578,7 @@ def __call__( http_options = ( _BaseLocalInventoryServiceRestTransport._BaseListLocalInventories._get_http_options() ) + request, metadata = self._interceptor.pre_list_local_inventories( request, metadata ) @@ -489,6 +591,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.shopping.merchant.inventories_v1beta.LocalInventoryServiceClient.ListLocalInventories", + extra={ + "serviceName": "google.shopping.merchant.inventories.v1beta.LocalInventoryService", + "rpcName": "ListLocalInventories", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ( LocalInventoryServiceRestTransport._ListLocalInventories._get_response( @@ -511,7 +640,31 @@ def __call__( pb_resp = localinventory.ListLocalInventoriesResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_local_inventories(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + localinventory.ListLocalInventoriesResponse.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.shopping.merchant.inventories_v1beta.LocalInventoryServiceClient.list_local_inventories", + extra={ + "serviceName": "google.shopping.merchant.inventories.v1beta.LocalInventoryService", + "rpcName": "ListLocalInventories", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/async_client.py b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/async_client.py index bd282b0768bb..7ce92f97ef97 100644 --- a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/async_client.py +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -54,6 +55,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, RegionalInventoryServiceTransport from .transports.grpc_asyncio import RegionalInventoryServiceGrpcAsyncIOTransport +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 RegionalInventoryServiceAsyncClient: """Service to manage regional inventory for products. There is also @@ -275,6 +285,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.shopping.merchant.inventories_v1beta.RegionalInventoryServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.inventories.v1beta.RegionalInventoryService", + "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.shopping.merchant.inventories.v1beta.RegionalInventoryService", + "credentialsType": None, + }, + ) + async def list_regional_inventories( self, request: Optional[ @@ -284,7 +316,7 @@ async def list_regional_inventories( 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.ListRegionalInventoriesAsyncPager: r"""Lists the ``RegionalInventory`` resources for the given product in your merchant account. The response might contain fewer items @@ -336,8 +368,10 @@ async def sample_list_regional_inventories(): 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.shopping.merchant_inventories_v1beta.services.regional_inventory_service.pagers.ListRegionalInventoriesAsyncPager: @@ -412,7 +446,7 @@ async def insert_regional_inventory( *, 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]]] = (), ) -> regionalinventory.RegionalInventory: r"""Inserts a ``RegionalInventory`` to a given product in your merchant account. @@ -462,8 +496,10 @@ async def sample_insert_regional_inventory(): 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.shopping.merchant_inventories_v1beta.types.RegionalInventory: @@ -517,7 +553,7 @@ async def delete_regional_inventory( 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 the specified ``RegionalInventory`` resource from the given product in your merchant account. It might take up to an @@ -563,8 +599,10 @@ async def sample_delete_regional_inventory(): 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 diff --git a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/client.py b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/client.py index 6498c4d3b7dc..907abc8f8165 100644 --- a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/client.py +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.shopping.type.types import types from google.type import interval_pb2 # type: ignore @@ -595,6 +605,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( @@ -661,6 +675,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.shopping.merchant.inventories_v1beta.RegionalInventoryServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.inventories.v1beta.RegionalInventoryService", + "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.shopping.merchant.inventories.v1beta.RegionalInventoryService", + "credentialsType": None, + }, + ) + def list_regional_inventories( self, request: Optional[ @@ -670,7 +707,7 @@ def list_regional_inventories( 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.ListRegionalInventoriesPager: r"""Lists the ``RegionalInventory`` resources for the given product in your merchant account. The response might contain fewer items @@ -722,8 +759,10 @@ def sample_list_regional_inventories(): 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.shopping.merchant_inventories_v1beta.services.regional_inventory_service.pagers.ListRegionalInventoriesPager: @@ -797,7 +836,7 @@ def insert_regional_inventory( *, 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]]] = (), ) -> regionalinventory.RegionalInventory: r"""Inserts a ``RegionalInventory`` to a given product in your merchant account. @@ -847,8 +886,10 @@ def sample_insert_regional_inventory(): 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.shopping.merchant_inventories_v1beta.types.RegionalInventory: @@ -902,7 +943,7 @@ def delete_regional_inventory( 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 the specified ``RegionalInventory`` resource from the given product in your merchant account. It might take up to an @@ -948,8 +989,10 @@ def sample_delete_regional_inventory(): 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 diff --git a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/pagers.py b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/pagers.py index bf4c7bbb459c..4f4a49429075 100644 --- a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/pagers.py +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/pagers.py @@ -67,7 +67,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. @@ -81,8 +81,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 = regionalinventory.ListRegionalInventoriesRequest(request) @@ -143,7 +145,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. @@ -157,8 +159,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 = regionalinventory.ListRegionalInventoriesRequest(request) diff --git a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/grpc.py b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/grpc.py index 5215b94b2081..b4aabbb32b38 100644 --- a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/grpc.py +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -21,12 +24,90 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore +import proto # type: ignore from google.shopping.merchant_inventories_v1beta.types import regionalinventory from .base import DEFAULT_CLIENT_INFO, RegionalInventoryServiceTransport +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.shopping.merchant.inventories.v1beta.RegionalInventoryService", + "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.shopping.merchant.inventories.v1beta.RegionalInventoryService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class RegionalInventoryServiceGrpcTransport(RegionalInventoryServiceTransport): """gRPC backend transport for RegionalInventoryService. @@ -181,7 +262,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 @@ -264,7 +350,7 @@ def list_regional_inventories( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_regional_inventories" not in self._stubs: - self._stubs["list_regional_inventories"] = self.grpc_channel.unary_unary( + self._stubs["list_regional_inventories"] = self._logged_channel.unary_unary( "/google.shopping.merchant.inventories.v1beta.RegionalInventoryService/ListRegionalInventories", request_serializer=regionalinventory.ListRegionalInventoriesRequest.serialize, response_deserializer=regionalinventory.ListRegionalInventoriesResponse.deserialize, @@ -302,7 +388,7 @@ def insert_regional_inventory( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "insert_regional_inventory" not in self._stubs: - self._stubs["insert_regional_inventory"] = self.grpc_channel.unary_unary( + self._stubs["insert_regional_inventory"] = self._logged_channel.unary_unary( "/google.shopping.merchant.inventories.v1beta.RegionalInventoryService/InsertRegionalInventory", request_serializer=regionalinventory.InsertRegionalInventoryRequest.serialize, response_deserializer=regionalinventory.RegionalInventory.deserialize, @@ -332,7 +418,7 @@ def delete_regional_inventory( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_regional_inventory" not in self._stubs: - self._stubs["delete_regional_inventory"] = self.grpc_channel.unary_unary( + self._stubs["delete_regional_inventory"] = self._logged_channel.unary_unary( "/google.shopping.merchant.inventories.v1beta.RegionalInventoryService/DeleteRegionalInventory", request_serializer=regionalinventory.DeleteRegionalInventoryRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -340,7 +426,7 @@ def delete_regional_inventory( return self._stubs["delete_regional_inventory"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/grpc_asyncio.py index ee343ccd46f6..2c924edda86b 100644 --- a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -23,14 +26,93 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_inventories_v1beta.types import regionalinventory from .base import DEFAULT_CLIENT_INFO, RegionalInventoryServiceTransport from .grpc import RegionalInventoryServiceGrpcTransport +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.shopping.merchant.inventories.v1beta.RegionalInventoryService", + "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.shopping.merchant.inventories.v1beta.RegionalInventoryService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class RegionalInventoryServiceGrpcAsyncIOTransport(RegionalInventoryServiceTransport): """gRPC AsyncIO backend transport for RegionalInventoryService. @@ -228,10 +310,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 @@ -272,7 +357,7 @@ def list_regional_inventories( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_regional_inventories" not in self._stubs: - self._stubs["list_regional_inventories"] = self.grpc_channel.unary_unary( + self._stubs["list_regional_inventories"] = self._logged_channel.unary_unary( "/google.shopping.merchant.inventories.v1beta.RegionalInventoryService/ListRegionalInventories", request_serializer=regionalinventory.ListRegionalInventoriesRequest.serialize, response_deserializer=regionalinventory.ListRegionalInventoriesResponse.deserialize, @@ -310,7 +395,7 @@ def insert_regional_inventory( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "insert_regional_inventory" not in self._stubs: - self._stubs["insert_regional_inventory"] = self.grpc_channel.unary_unary( + self._stubs["insert_regional_inventory"] = self._logged_channel.unary_unary( "/google.shopping.merchant.inventories.v1beta.RegionalInventoryService/InsertRegionalInventory", request_serializer=regionalinventory.InsertRegionalInventoryRequest.serialize, response_deserializer=regionalinventory.RegionalInventory.deserialize, @@ -342,7 +427,7 @@ def delete_regional_inventory( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_regional_inventory" not in self._stubs: - self._stubs["delete_regional_inventory"] = self.grpc_channel.unary_unary( + self._stubs["delete_regional_inventory"] = self._logged_channel.unary_unary( "/google.shopping.merchant.inventories.v1beta.RegionalInventoryService/DeleteRegionalInventory", request_serializer=regionalinventory.DeleteRegionalInventoryRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -375,7 +460,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/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/rest.py b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/rest.py index 9c4f8f69ed40..e03a5e4fa4ec 100644 --- a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/rest.py +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -38,6 +38,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, @@ -90,9 +98,10 @@ def post_list_regional_inventories(self, response): def pre_delete_regional_inventory( self, request: regionalinventory.DeleteRegionalInventoryRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - regionalinventory.DeleteRegionalInventoryRequest, Sequence[Tuple[str, str]] + regionalinventory.DeleteRegionalInventoryRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for delete_regional_inventory @@ -104,9 +113,10 @@ def pre_delete_regional_inventory( def pre_insert_regional_inventory( self, request: regionalinventory.InsertRegionalInventoryRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - regionalinventory.InsertRegionalInventoryRequest, Sequence[Tuple[str, str]] + regionalinventory.InsertRegionalInventoryRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for insert_regional_inventory @@ -129,9 +139,10 @@ def post_insert_regional_inventory( def pre_list_regional_inventories( self, request: regionalinventory.ListRegionalInventoriesRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - regionalinventory.ListRegionalInventoriesRequest, Sequence[Tuple[str, str]] + regionalinventory.ListRegionalInventoriesRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for list_regional_inventories @@ -274,7 +285,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 regional inventory method over HTTP. @@ -285,13 +296,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 = ( _BaseRegionalInventoryServiceRestTransport._BaseDeleteRegionalInventory._get_http_options() ) + request, metadata = self._interceptor.pre_delete_regional_inventory( request, metadata ) @@ -304,6 +318,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.shopping.merchant.inventories_v1beta.RegionalInventoryServiceClient.DeleteRegionalInventory", + extra={ + "serviceName": "google.shopping.merchant.inventories.v1beta.RegionalInventoryService", + "rpcName": "DeleteRegionalInventory", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = RegionalInventoryServiceRestTransport._DeleteRegionalInventory._get_response( self._host, @@ -355,7 +396,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]]] = (), ) -> regionalinventory.RegionalInventory: r"""Call the insert regional inventory method over HTTP. @@ -366,8 +407,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: ~.regionalinventory.RegionalInventory: @@ -384,6 +427,7 @@ def __call__( http_options = ( _BaseRegionalInventoryServiceRestTransport._BaseInsertRegionalInventory._get_http_options() ) + request, metadata = self._interceptor.pre_insert_regional_inventory( request, metadata ) @@ -400,6 +444,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.shopping.merchant.inventories_v1beta.RegionalInventoryServiceClient.InsertRegionalInventory", + extra={ + "serviceName": "google.shopping.merchant.inventories.v1beta.RegionalInventoryService", + "rpcName": "InsertRegionalInventory", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = RegionalInventoryServiceRestTransport._InsertRegionalInventory._get_response( self._host, @@ -421,7 +492,31 @@ def __call__( pb_resp = regionalinventory.RegionalInventory.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_insert_regional_inventory(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = regionalinventory.RegionalInventory.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.shopping.merchant.inventories_v1beta.RegionalInventoryServiceClient.insert_regional_inventory", + extra={ + "serviceName": "google.shopping.merchant.inventories.v1beta.RegionalInventoryService", + "rpcName": "InsertRegionalInventory", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListRegionalInventories( @@ -459,7 +554,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]]] = (), ) -> regionalinventory.ListRegionalInventoriesResponse: r"""Call the list regional inventories method over HTTP. @@ -470,8 +565,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: ~.regionalinventory.ListRegionalInventoriesResponse: @@ -483,6 +580,7 @@ def __call__( http_options = ( _BaseRegionalInventoryServiceRestTransport._BaseListRegionalInventories._get_http_options() ) + request, metadata = self._interceptor.pre_list_regional_inventories( request, metadata ) @@ -495,6 +593,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.shopping.merchant.inventories_v1beta.RegionalInventoryServiceClient.ListRegionalInventories", + extra={ + "serviceName": "google.shopping.merchant.inventories.v1beta.RegionalInventoryService", + "rpcName": "ListRegionalInventories", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = RegionalInventoryServiceRestTransport._ListRegionalInventories._get_response( self._host, @@ -515,7 +640,33 @@ def __call__( pb_resp = regionalinventory.ListRegionalInventoriesResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_regional_inventories(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + regionalinventory.ListRegionalInventoriesResponse.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.shopping.merchant.inventories_v1beta.RegionalInventoryServiceClient.list_regional_inventories", + extra={ + "serviceName": "google.shopping.merchant.inventories.v1beta.RegionalInventoryService", + "rpcName": "ListRegionalInventories", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-inventories/samples/generated_samples/snippet_metadata_google.shopping.merchant.inventories.v1beta.json b/packages/google-shopping-merchant-inventories/samples/generated_samples/snippet_metadata_google.shopping.merchant.inventories.v1beta.json index 7366fa8519af..73ddfcf94070 100644 --- a/packages/google-shopping-merchant-inventories/samples/generated_samples/snippet_metadata_google.shopping.merchant.inventories.v1beta.json +++ b/packages/google-shopping-merchant-inventories/samples/generated_samples/snippet_metadata_google.shopping.merchant.inventories.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-shopping-merchant-inventories", - "version": "0.1.11" + "version": "0.1.0" }, "snippets": [ { @@ -47,7 +47,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_local_inventory" @@ -124,7 +124,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_local_inventory" @@ -198,7 +198,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_inventories_v1beta.types.LocalInventory", @@ -274,7 +274,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_inventories_v1beta.types.LocalInventory", @@ -355,7 +355,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_inventories_v1beta.services.local_inventory_service.pagers.ListLocalInventoriesAsyncPager", @@ -435,7 +435,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_inventories_v1beta.services.local_inventory_service.pagers.ListLocalInventoriesPager", @@ -516,7 +516,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_regional_inventory" @@ -593,7 +593,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_regional_inventory" @@ -667,7 +667,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_inventories_v1beta.types.RegionalInventory", @@ -743,7 +743,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_inventories_v1beta.types.RegionalInventory", @@ -824,7 +824,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_inventories_v1beta.services.regional_inventory_service.pagers.ListRegionalInventoriesAsyncPager", @@ -904,7 +904,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_inventories_v1beta.services.regional_inventory_service.pagers.ListRegionalInventoriesPager", diff --git a/packages/google-shopping-merchant-inventories/tests/unit/gapic/merchant_inventories_v1beta/test_local_inventory_service.py b/packages/google-shopping-merchant-inventories/tests/unit/gapic/merchant_inventories_v1beta/test_local_inventory_service.py index b62c5e6296cc..12a25e57fe34 100644 --- a/packages/google-shopping-merchant-inventories/tests/unit/gapic/merchant_inventories_v1beta/test_local_inventory_service.py +++ b/packages/google-shopping-merchant-inventories/tests/unit/gapic/merchant_inventories_v1beta/test_local_inventory_service.py @@ -2402,6 +2402,7 @@ def test_list_local_inventories_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_local_inventories(request) @@ -2455,6 +2456,7 @@ def test_list_local_inventories_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_local_inventories(**mock_args) @@ -2655,6 +2657,7 @@ def test_insert_local_inventory_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.insert_local_inventory(request) @@ -2784,6 +2787,7 @@ def test_delete_local_inventory_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_local_inventory(request) @@ -2829,6 +2833,7 @@ def test_delete_local_inventory_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_local_inventory(**mock_args) @@ -3165,6 +3170,7 @@ def test_list_local_inventories_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_local_inventories(request) @@ -3200,6 +3206,7 @@ def test_list_local_inventories_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_local_inventories(request) # Establish that the response is the type that we expect. @@ -3240,6 +3247,7 @@ def test_list_local_inventories_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 = localinventory.ListLocalInventoriesResponse.to_json( localinventory.ListLocalInventoriesResponse() ) @@ -3286,6 +3294,7 @@ def test_insert_local_inventory_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.insert_local_inventory(request) @@ -3416,6 +3425,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.insert_local_inventory(request) # Establish that the response is the type that we expect. @@ -3463,6 +3473,7 @@ def test_insert_local_inventory_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 = localinventory.LocalInventory.to_json( localinventory.LocalInventory() ) @@ -3511,6 +3522,7 @@ def test_delete_local_inventory_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_local_inventory(request) @@ -3543,6 +3555,7 @@ def test_delete_local_inventory_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_local_inventory(request) # Establish that the response is the type that we expect. @@ -3579,6 +3592,7 @@ def test_delete_local_inventory_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 = localinventory.DeleteLocalInventoryRequest() metadata = [ diff --git a/packages/google-shopping-merchant-inventories/tests/unit/gapic/merchant_inventories_v1beta/test_regional_inventory_service.py b/packages/google-shopping-merchant-inventories/tests/unit/gapic/merchant_inventories_v1beta/test_regional_inventory_service.py index f6137265258b..ca08ede3303e 100644 --- a/packages/google-shopping-merchant-inventories/tests/unit/gapic/merchant_inventories_v1beta/test_regional_inventory_service.py +++ b/packages/google-shopping-merchant-inventories/tests/unit/gapic/merchant_inventories_v1beta/test_regional_inventory_service.py @@ -2400,6 +2400,7 @@ def test_list_regional_inventories_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_regional_inventories(request) @@ -2455,6 +2456,7 @@ def test_list_regional_inventories_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_regional_inventories(**mock_args) @@ -2656,6 +2658,7 @@ def test_insert_regional_inventory_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.insert_regional_inventory(request) @@ -2785,6 +2788,7 @@ def test_delete_regional_inventory_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_regional_inventory(request) @@ -2830,6 +2834,7 @@ def test_delete_regional_inventory_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_regional_inventory(**mock_args) @@ -3162,6 +3167,7 @@ def test_list_regional_inventories_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_regional_inventories(request) @@ -3199,6 +3205,7 @@ def test_list_regional_inventories_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_regional_inventories(request) # Establish that the response is the type that we expect. @@ -3241,6 +3248,7 @@ def test_list_regional_inventories_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 = regionalinventory.ListRegionalInventoriesResponse.to_json( regionalinventory.ListRegionalInventoriesResponse() ) @@ -3287,6 +3295,7 @@ def test_insert_regional_inventory_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.insert_regional_inventory(request) @@ -3409,6 +3418,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.insert_regional_inventory(request) # Establish that the response is the type that we expect. @@ -3454,6 +3464,7 @@ def test_insert_regional_inventory_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 = regionalinventory.RegionalInventory.to_json( regionalinventory.RegionalInventory() ) @@ -3502,6 +3513,7 @@ def test_delete_regional_inventory_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_regional_inventory(request) @@ -3534,6 +3546,7 @@ def test_delete_regional_inventory_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_regional_inventory(request) # Establish that the response is the type that we expect. @@ -3571,6 +3584,7 @@ def test_delete_regional_inventory_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 = regionalinventory.DeleteRegionalInventoryRequest() metadata = [ diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp/gapic_version.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp/gapic_version.py index e9c4bb5650f3..558c8aab67c5 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp/gapic_version.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.5" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/gapic_version.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/gapic_version.py index e9c4bb5650f3..558c8aab67c5 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/gapic_version.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.5" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/async_client.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/async_client.py index 58e49da98983..acc3b3c969da 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/async_client.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -51,6 +52,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, LfpInventoryServiceTransport from .transports.grpc_asyncio import LfpInventoryServiceGrpcAsyncIOTransport +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 LfpInventoryServiceAsyncClient: """Service for a `LFP @@ -265,13 +275,35 @@ def __init__( client_info=client_info, ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.shopping.merchant.lfp_v1beta.LfpInventoryServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.lfp.v1beta.LfpInventoryService", + "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.shopping.merchant.lfp.v1beta.LfpInventoryService", + "credentialsType": None, + }, + ) + async def insert_lfp_inventory( self, request: Optional[Union[lfpinventory.InsertLfpInventoryRequest, dict]] = 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]]] = (), ) -> lfpinventory.LfpInventory: r"""Inserts a ``LfpInventory`` resource for the given target merchant account. If the resource already exists, it will be @@ -318,8 +350,10 @@ async def sample_insert_lfp_inventory(): 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.shopping.merchant_lfp_v1beta.types.LfpInventory: diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/client.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/client.py index 0004840ef92b..08c5e1569a61 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/client.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.protobuf import timestamp_pb2 # type: ignore from google.shopping.type.types import types @@ -589,6 +599,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( @@ -655,13 +669,36 @@ 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.shopping.merchant.lfp_v1beta.LfpInventoryServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.lfp.v1beta.LfpInventoryService", + "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.shopping.merchant.lfp.v1beta.LfpInventoryService", + "credentialsType": None, + }, + ) + def insert_lfp_inventory( self, request: Optional[Union[lfpinventory.InsertLfpInventoryRequest, dict]] = 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]]] = (), ) -> lfpinventory.LfpInventory: r"""Inserts a ``LfpInventory`` resource for the given target merchant account. If the resource already exists, it will be @@ -708,8 +745,10 @@ def sample_insert_lfp_inventory(): 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.shopping.merchant_lfp_v1beta.types.LfpInventory: diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/grpc.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/grpc.py index 24517af1b5fd..3215cd86350a 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/grpc.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -20,12 +23,90 @@ 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.shopping.merchant_lfp_v1beta.types import lfpinventory from .base import DEFAULT_CLIENT_INFO, LfpInventoryServiceTransport +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.shopping.merchant.lfp.v1beta.LfpInventoryService", + "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.shopping.merchant.lfp.v1beta.LfpInventoryService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class LfpInventoryServiceGrpcTransport(LfpInventoryServiceTransport): """gRPC backend transport for LfpInventoryService. @@ -181,7 +262,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 @@ -257,7 +343,7 @@ def insert_lfp_inventory( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "insert_lfp_inventory" not in self._stubs: - self._stubs["insert_lfp_inventory"] = self.grpc_channel.unary_unary( + self._stubs["insert_lfp_inventory"] = self._logged_channel.unary_unary( "/google.shopping.merchant.lfp.v1beta.LfpInventoryService/InsertLfpInventory", request_serializer=lfpinventory.InsertLfpInventoryRequest.serialize, response_deserializer=lfpinventory.LfpInventory.deserialize, @@ -265,7 +351,7 @@ def insert_lfp_inventory( return self._stubs["insert_lfp_inventory"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/grpc_asyncio.py index 5aed7328c0f1..815c271b8ebd 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -22,14 +25,93 @@ 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 from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_lfp_v1beta.types import lfpinventory from .base import DEFAULT_CLIENT_INFO, LfpInventoryServiceTransport from .grpc import LfpInventoryServiceGrpcTransport +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.shopping.merchant.lfp.v1beta.LfpInventoryService", + "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.shopping.merchant.lfp.v1beta.LfpInventoryService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class LfpInventoryServiceGrpcAsyncIOTransport(LfpInventoryServiceTransport): """gRPC AsyncIO backend transport for LfpInventoryService. @@ -228,10 +310,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 @@ -267,7 +352,7 @@ def insert_lfp_inventory( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "insert_lfp_inventory" not in self._stubs: - self._stubs["insert_lfp_inventory"] = self.grpc_channel.unary_unary( + self._stubs["insert_lfp_inventory"] = self._logged_channel.unary_unary( "/google.shopping.merchant.lfp.v1beta.LfpInventoryService/InsertLfpInventory", request_serializer=lfpinventory.InsertLfpInventoryRequest.serialize, response_deserializer=lfpinventory.LfpInventory.deserialize, @@ -290,7 +375,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/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/rest.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/rest.py index f123a2fa4f5e..3db7ac1e849a 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/rest.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -37,6 +37,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, @@ -77,8 +85,10 @@ def post_insert_lfp_inventory(self, response): def pre_insert_lfp_inventory( self, request: lfpinventory.InsertLfpInventoryRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[lfpinventory.InsertLfpInventoryRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + lfpinventory.InsertLfpInventoryRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for insert_lfp_inventory Override in a subclass to manipulate the request or metadata @@ -222,7 +232,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]]] = (), ) -> lfpinventory.LfpInventory: r"""Call the insert lfp inventory method over HTTP. @@ -232,8 +242,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: ~.lfpinventory.LfpInventory: @@ -243,6 +255,7 @@ def __call__( http_options = ( _BaseLfpInventoryServiceRestTransport._BaseInsertLfpInventory._get_http_options() ) + request, metadata = self._interceptor.pre_insert_lfp_inventory( request, metadata ) @@ -259,6 +272,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.shopping.merchant.lfp_v1beta.LfpInventoryServiceClient.InsertLfpInventory", + extra={ + "serviceName": "google.shopping.merchant.lfp.v1beta.LfpInventoryService", + "rpcName": "InsertLfpInventory", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ( LfpInventoryServiceRestTransport._InsertLfpInventory._get_response( @@ -282,7 +322,29 @@ def __call__( pb_resp = lfpinventory.LfpInventory.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_insert_lfp_inventory(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = lfpinventory.LfpInventory.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.shopping.merchant.lfp_v1beta.LfpInventoryServiceClient.insert_lfp_inventory", + extra={ + "serviceName": "google.shopping.merchant.lfp.v1beta.LfpInventoryService", + "rpcName": "InsertLfpInventory", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/async_client.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/async_client.py index 57a52a52191d..6d6d8c5425e4 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/async_client.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -51,6 +52,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, LfpSaleServiceTransport from .transports.grpc_asyncio import LfpSaleServiceGrpcAsyncIOTransport +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 LfpSaleServiceAsyncClient: """Service for a `LFP @@ -259,13 +269,35 @@ def __init__( client_info=client_info, ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.shopping.merchant.lfp_v1beta.LfpSaleServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.lfp.v1beta.LfpSaleService", + "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.shopping.merchant.lfp.v1beta.LfpSaleService", + "credentialsType": None, + }, + ) + async def insert_lfp_sale( self, request: Optional[Union[lfpsale.InsertLfpSaleRequest, dict]] = 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]]] = (), ) -> lfpsale.LfpSale: r"""Inserts a ``LfpSale`` for the given merchant. @@ -312,8 +344,10 @@ async def sample_insert_lfp_sale(): 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.shopping.merchant_lfp_v1beta.types.LfpSale: diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/client.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/client.py index 8d9680438f32..ffc314249a51 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/client.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.protobuf import timestamp_pb2 # type: ignore from google.shopping.type.types import types @@ -578,6 +588,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( @@ -643,13 +657,36 @@ 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.shopping.merchant.lfp_v1beta.LfpSaleServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.lfp.v1beta.LfpSaleService", + "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.shopping.merchant.lfp.v1beta.LfpSaleService", + "credentialsType": None, + }, + ) + def insert_lfp_sale( self, request: Optional[Union[lfpsale.InsertLfpSaleRequest, dict]] = 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]]] = (), ) -> lfpsale.LfpSale: r"""Inserts a ``LfpSale`` for the given merchant. @@ -696,8 +733,10 @@ def sample_insert_lfp_sale(): 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.shopping.merchant_lfp_v1beta.types.LfpSale: diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/grpc.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/grpc.py index c2b62f09e328..acd05e27962d 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/grpc.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -20,12 +23,90 @@ 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.shopping.merchant_lfp_v1beta.types import lfpsale from .base import DEFAULT_CLIENT_INFO, LfpSaleServiceTransport +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.shopping.merchant.lfp.v1beta.LfpSaleService", + "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.shopping.merchant.lfp.v1beta.LfpSaleService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class LfpSaleServiceGrpcTransport(LfpSaleServiceTransport): """gRPC backend transport for LfpSaleService. @@ -181,7 +262,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 @@ -255,7 +341,7 @@ def insert_lfp_sale( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "insert_lfp_sale" not in self._stubs: - self._stubs["insert_lfp_sale"] = self.grpc_channel.unary_unary( + self._stubs["insert_lfp_sale"] = self._logged_channel.unary_unary( "/google.shopping.merchant.lfp.v1beta.LfpSaleService/InsertLfpSale", request_serializer=lfpsale.InsertLfpSaleRequest.serialize, response_deserializer=lfpsale.LfpSale.deserialize, @@ -263,7 +349,7 @@ def insert_lfp_sale( return self._stubs["insert_lfp_sale"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/grpc_asyncio.py index f8df8912c3a0..7b17a78c8367 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -22,14 +25,93 @@ 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 from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_lfp_v1beta.types import lfpsale from .base import DEFAULT_CLIENT_INFO, LfpSaleServiceTransport from .grpc import LfpSaleServiceGrpcTransport +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.shopping.merchant.lfp.v1beta.LfpSaleService", + "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.shopping.merchant.lfp.v1beta.LfpSaleService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class LfpSaleServiceGrpcAsyncIOTransport(LfpSaleServiceTransport): """gRPC AsyncIO backend transport for LfpSaleService. @@ -228,10 +310,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 @@ -263,7 +348,7 @@ def insert_lfp_sale( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "insert_lfp_sale" not in self._stubs: - self._stubs["insert_lfp_sale"] = self.grpc_channel.unary_unary( + self._stubs["insert_lfp_sale"] = self._logged_channel.unary_unary( "/google.shopping.merchant.lfp.v1beta.LfpSaleService/InsertLfpSale", request_serializer=lfpsale.InsertLfpSaleRequest.serialize, response_deserializer=lfpsale.LfpSale.deserialize, @@ -286,7 +371,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/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/rest.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/rest.py index e0078cda11d2..e80adff4996a 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/rest.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -37,6 +37,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, @@ -75,8 +83,10 @@ def post_insert_lfp_sale(self, response): """ def pre_insert_lfp_sale( - self, request: lfpsale.InsertLfpSaleRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[lfpsale.InsertLfpSaleRequest, Sequence[Tuple[str, str]]]: + self, + request: lfpsale.InsertLfpSaleRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[lfpsale.InsertLfpSaleRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for insert_lfp_sale Override in a subclass to manipulate the request or metadata @@ -217,7 +227,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]]] = (), ) -> lfpsale.LfpSale: r"""Call the insert lfp sale method over HTTP. @@ -228,8 +238,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: ~.lfpsale.LfpSale: @@ -239,6 +251,7 @@ def __call__( http_options = ( _BaseLfpSaleServiceRestTransport._BaseInsertLfpSale._get_http_options() ) + request, metadata = self._interceptor.pre_insert_lfp_sale(request, metadata) transcoded_request = _BaseLfpSaleServiceRestTransport._BaseInsertLfpSale._get_transcoded_request( http_options, request @@ -253,6 +266,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.shopping.merchant.lfp_v1beta.LfpSaleServiceClient.InsertLfpSale", + extra={ + "serviceName": "google.shopping.merchant.lfp.v1beta.LfpSaleService", + "rpcName": "InsertLfpSale", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = LfpSaleServiceRestTransport._InsertLfpSale._get_response( self._host, @@ -274,7 +314,29 @@ def __call__( pb_resp = lfpsale.LfpSale.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_insert_lfp_sale(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = lfpsale.LfpSale.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.shopping.merchant.lfp_v1beta.LfpSaleServiceClient.insert_lfp_sale", + extra={ + "serviceName": "google.shopping.merchant.lfp.v1beta.LfpSaleService", + "rpcName": "InsertLfpSale", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/async_client.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/async_client.py index 5dce7e0b8308..dec2590e5004 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/async_client.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -49,6 +50,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, LfpStoreServiceTransport from .transports.grpc_asyncio import LfpStoreServiceGrpcAsyncIOTransport +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 LfpStoreServiceAsyncClient: """Service for a `LFP @@ -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.shopping.merchant.lfp_v1beta.LfpStoreServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.lfp.v1beta.LfpStoreService", + "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.shopping.merchant.lfp.v1beta.LfpStoreService", + "credentialsType": None, + }, + ) + async def get_lfp_store( self, request: Optional[Union[lfpstore.GetLfpStoreRequest, dict]] = None, @@ -266,7 +298,7 @@ async def get_lfp_store( 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]]] = (), ) -> lfpstore.LfpStore: r"""Retrieves information about a store. @@ -309,8 +341,10 @@ async def sample_get_lfp_store(): 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.shopping.merchant_lfp_v1beta.types.LfpStore: @@ -377,7 +411,7 @@ async def insert_lfp_store( lfp_store: Optional[lfpstore.LfpStore] = 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]]] = (), ) -> lfpstore.LfpStore: r"""Inserts a store for the target merchant. If the store with the same store code already exists, it will be @@ -434,8 +468,10 @@ async def sample_insert_lfp_store(): 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.shopping.merchant_lfp_v1beta.types.LfpStore: @@ -503,7 +539,7 @@ async def delete_lfp_store( 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 store for a target merchant. @@ -545,8 +581,10 @@ async def sample_delete_lfp_store(): 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 @@ -598,7 +636,7 @@ async def list_lfp_stores( 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.ListLfpStoresAsyncPager: r"""Lists the stores of the target merchant, specified by the filter in ``ListLfpStoresRequest``. @@ -645,8 +683,10 @@ async def sample_list_lfp_stores(): 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.shopping.merchant_lfp_v1beta.services.lfp_store_service.pagers.ListLfpStoresAsyncPager: diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/client.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/client.py index 215a690fa986..8cfbe2326013 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/client.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.shopping.merchant_lfp_v1beta.services.lfp_store_service import pagers from google.shopping.merchant_lfp_v1beta.types import lfpstore @@ -583,6 +593,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( @@ -648,6 +662,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.shopping.merchant.lfp_v1beta.LfpStoreServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.lfp.v1beta.LfpStoreService", + "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.shopping.merchant.lfp.v1beta.LfpStoreService", + "credentialsType": None, + }, + ) + def get_lfp_store( self, request: Optional[Union[lfpstore.GetLfpStoreRequest, dict]] = None, @@ -655,7 +692,7 @@ def get_lfp_store( 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]]] = (), ) -> lfpstore.LfpStore: r"""Retrieves information about a store. @@ -698,8 +735,10 @@ def sample_get_lfp_store(): 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.shopping.merchant_lfp_v1beta.types.LfpStore: @@ -763,7 +802,7 @@ def insert_lfp_store( lfp_store: Optional[lfpstore.LfpStore] = 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]]] = (), ) -> lfpstore.LfpStore: r"""Inserts a store for the target merchant. If the store with the same store code already exists, it will be @@ -820,8 +859,10 @@ def sample_insert_lfp_store(): 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.shopping.merchant_lfp_v1beta.types.LfpStore: @@ -886,7 +927,7 @@ def delete_lfp_store( 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 store for a target merchant. @@ -928,8 +969,10 @@ def sample_delete_lfp_store(): 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 @@ -978,7 +1021,7 @@ def list_lfp_stores( 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.ListLfpStoresPager: r"""Lists the stores of the target merchant, specified by the filter in ``ListLfpStoresRequest``. @@ -1025,8 +1068,10 @@ def sample_list_lfp_stores(): 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.shopping.merchant_lfp_v1beta.services.lfp_store_service.pagers.ListLfpStoresPager: diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/pagers.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/pagers.py index c44b51d871ce..b0ab17b0610d 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/pagers.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/pagers.py @@ -67,7 +67,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. @@ -81,8 +81,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 = lfpstore.ListLfpStoresRequest(request) @@ -141,7 +143,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. @@ -155,8 +157,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 = lfpstore.ListLfpStoresRequest(request) diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/grpc.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/grpc.py index 5ca5fc03a6dc..4a92a3d5663b 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/grpc.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -21,12 +24,90 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore +import proto # type: ignore from google.shopping.merchant_lfp_v1beta.types import lfpstore from .base import DEFAULT_CLIENT_INFO, LfpStoreServiceTransport +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.shopping.merchant.lfp.v1beta.LfpStoreService", + "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.shopping.merchant.lfp.v1beta.LfpStoreService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class LfpStoreServiceGrpcTransport(LfpStoreServiceTransport): """gRPC backend transport for LfpStoreService. @@ -182,7 +263,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 @@ -256,7 +342,7 @@ def get_lfp_store( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_lfp_store" not in self._stubs: - self._stubs["get_lfp_store"] = self.grpc_channel.unary_unary( + self._stubs["get_lfp_store"] = self._logged_channel.unary_unary( "/google.shopping.merchant.lfp.v1beta.LfpStoreService/GetLfpStore", request_serializer=lfpstore.GetLfpStoreRequest.serialize, response_deserializer=lfpstore.LfpStore.deserialize, @@ -284,7 +370,7 @@ def insert_lfp_store( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "insert_lfp_store" not in self._stubs: - self._stubs["insert_lfp_store"] = self.grpc_channel.unary_unary( + self._stubs["insert_lfp_store"] = self._logged_channel.unary_unary( "/google.shopping.merchant.lfp.v1beta.LfpStoreService/InsertLfpStore", request_serializer=lfpstore.InsertLfpStoreRequest.serialize, response_deserializer=lfpstore.LfpStore.deserialize, @@ -310,7 +396,7 @@ def delete_lfp_store( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_lfp_store" not in self._stubs: - self._stubs["delete_lfp_store"] = self.grpc_channel.unary_unary( + self._stubs["delete_lfp_store"] = self._logged_channel.unary_unary( "/google.shopping.merchant.lfp.v1beta.LfpStoreService/DeleteLfpStore", request_serializer=lfpstore.DeleteLfpStoreRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -337,7 +423,7 @@ def list_lfp_stores( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_lfp_stores" not in self._stubs: - self._stubs["list_lfp_stores"] = self.grpc_channel.unary_unary( + self._stubs["list_lfp_stores"] = self._logged_channel.unary_unary( "/google.shopping.merchant.lfp.v1beta.LfpStoreService/ListLfpStores", request_serializer=lfpstore.ListLfpStoresRequest.serialize, response_deserializer=lfpstore.ListLfpStoresResponse.deserialize, @@ -345,7 +431,7 @@ def list_lfp_stores( return self._stubs["list_lfp_stores"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/grpc_asyncio.py index f15ccebf5497..0911923e5dab 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -23,14 +26,93 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_lfp_v1beta.types import lfpstore from .base import DEFAULT_CLIENT_INFO, LfpStoreServiceTransport from .grpc import LfpStoreServiceGrpcTransport +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.shopping.merchant.lfp.v1beta.LfpStoreService", + "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.shopping.merchant.lfp.v1beta.LfpStoreService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class LfpStoreServiceGrpcAsyncIOTransport(LfpStoreServiceTransport): """gRPC AsyncIO backend transport for LfpStoreService. @@ -229,10 +311,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 @@ -264,7 +349,7 @@ def get_lfp_store( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_lfp_store" not in self._stubs: - self._stubs["get_lfp_store"] = self.grpc_channel.unary_unary( + self._stubs["get_lfp_store"] = self._logged_channel.unary_unary( "/google.shopping.merchant.lfp.v1beta.LfpStoreService/GetLfpStore", request_serializer=lfpstore.GetLfpStoreRequest.serialize, response_deserializer=lfpstore.LfpStore.deserialize, @@ -292,7 +377,7 @@ def insert_lfp_store( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "insert_lfp_store" not in self._stubs: - self._stubs["insert_lfp_store"] = self.grpc_channel.unary_unary( + self._stubs["insert_lfp_store"] = self._logged_channel.unary_unary( "/google.shopping.merchant.lfp.v1beta.LfpStoreService/InsertLfpStore", request_serializer=lfpstore.InsertLfpStoreRequest.serialize, response_deserializer=lfpstore.LfpStore.deserialize, @@ -318,7 +403,7 @@ def delete_lfp_store( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_lfp_store" not in self._stubs: - self._stubs["delete_lfp_store"] = self.grpc_channel.unary_unary( + self._stubs["delete_lfp_store"] = self._logged_channel.unary_unary( "/google.shopping.merchant.lfp.v1beta.LfpStoreService/DeleteLfpStore", request_serializer=lfpstore.DeleteLfpStoreRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -347,7 +432,7 @@ def list_lfp_stores( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_lfp_stores" not in self._stubs: - self._stubs["list_lfp_stores"] = self.grpc_channel.unary_unary( + self._stubs["list_lfp_stores"] = self._logged_channel.unary_unary( "/google.shopping.merchant.lfp.v1beta.LfpStoreService/ListLfpStores", request_serializer=lfpstore.ListLfpStoresRequest.serialize, response_deserializer=lfpstore.ListLfpStoresResponse.deserialize, @@ -385,7 +470,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/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/rest.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/rest.py index 7a07da90e2c7..c9ef2b40314b 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/rest.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -38,6 +38,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, @@ -98,8 +106,8 @@ def post_list_lfp_stores(self, response): def pre_delete_lfp_store( self, request: lfpstore.DeleteLfpStoreRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[lfpstore.DeleteLfpStoreRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[lfpstore.DeleteLfpStoreRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for delete_lfp_store Override in a subclass to manipulate the request or metadata @@ -108,8 +116,10 @@ def pre_delete_lfp_store( return request, metadata def pre_get_lfp_store( - self, request: lfpstore.GetLfpStoreRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[lfpstore.GetLfpStoreRequest, Sequence[Tuple[str, str]]]: + self, + request: lfpstore.GetLfpStoreRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[lfpstore.GetLfpStoreRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for get_lfp_store Override in a subclass to manipulate the request or metadata @@ -129,8 +139,8 @@ def post_get_lfp_store(self, response: lfpstore.LfpStore) -> lfpstore.LfpStore: def pre_insert_lfp_store( self, request: lfpstore.InsertLfpStoreRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[lfpstore.InsertLfpStoreRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[lfpstore.InsertLfpStoreRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for insert_lfp_store Override in a subclass to manipulate the request or metadata @@ -150,8 +160,8 @@ def post_insert_lfp_store(self, response: lfpstore.LfpStore) -> lfpstore.LfpStor def pre_list_lfp_stores( self, request: lfpstore.ListLfpStoresRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[lfpstore.ListLfpStoresRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[lfpstore.ListLfpStoresRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for list_lfp_stores Override in a subclass to manipulate the request or metadata @@ -293,7 +303,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 lfp store method over HTTP. @@ -304,13 +314,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 = ( _BaseLfpStoreServiceRestTransport._BaseDeleteLfpStore._get_http_options() ) + request, metadata = self._interceptor.pre_delete_lfp_store( request, metadata ) @@ -323,6 +336,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.shopping.merchant.lfp_v1beta.LfpStoreServiceClient.DeleteLfpStore", + extra={ + "serviceName": "google.shopping.merchant.lfp.v1beta.LfpStoreService", + "rpcName": "DeleteLfpStore", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = LfpStoreServiceRestTransport._DeleteLfpStore._get_response( self._host, @@ -372,7 +412,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]]] = (), ) -> lfpstore.LfpStore: r"""Call the get lfp store method over HTTP. @@ -382,8 +422,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: ~.lfpstore.LfpStore: @@ -400,6 +442,7 @@ def __call__( http_options = ( _BaseLfpStoreServiceRestTransport._BaseGetLfpStore._get_http_options() ) + request, metadata = self._interceptor.pre_get_lfp_store(request, metadata) transcoded_request = _BaseLfpStoreServiceRestTransport._BaseGetLfpStore._get_transcoded_request( http_options, request @@ -410,6 +453,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.shopping.merchant.lfp_v1beta.LfpStoreServiceClient.GetLfpStore", + extra={ + "serviceName": "google.shopping.merchant.lfp.v1beta.LfpStoreService", + "rpcName": "GetLfpStore", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = LfpStoreServiceRestTransport._GetLfpStore._get_response( self._host, @@ -430,7 +500,29 @@ def __call__( pb_resp = lfpstore.LfpStore.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_lfp_store(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = lfpstore.LfpStore.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.shopping.merchant.lfp_v1beta.LfpStoreServiceClient.get_lfp_store", + extra={ + "serviceName": "google.shopping.merchant.lfp.v1beta.LfpStoreService", + "rpcName": "GetLfpStore", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _InsertLfpStore( @@ -468,7 +560,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]]] = (), ) -> lfpstore.LfpStore: r"""Call the insert lfp store method over HTTP. @@ -479,8 +571,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: ~.lfpstore.LfpStore: @@ -497,6 +591,7 @@ def __call__( http_options = ( _BaseLfpStoreServiceRestTransport._BaseInsertLfpStore._get_http_options() ) + request, metadata = self._interceptor.pre_insert_lfp_store( request, metadata ) @@ -513,6 +608,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.shopping.merchant.lfp_v1beta.LfpStoreServiceClient.InsertLfpStore", + extra={ + "serviceName": "google.shopping.merchant.lfp.v1beta.LfpStoreService", + "rpcName": "InsertLfpStore", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = LfpStoreServiceRestTransport._InsertLfpStore._get_response( self._host, @@ -534,7 +656,29 @@ def __call__( pb_resp = lfpstore.LfpStore.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_insert_lfp_store(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = lfpstore.LfpStore.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.shopping.merchant.lfp_v1beta.LfpStoreServiceClient.insert_lfp_store", + extra={ + "serviceName": "google.shopping.merchant.lfp.v1beta.LfpStoreService", + "rpcName": "InsertLfpStore", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListLfpStores( @@ -571,7 +715,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]]] = (), ) -> lfpstore.ListLfpStoresResponse: r"""Call the list lfp stores method over HTTP. @@ -582,8 +726,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: ~.lfpstore.ListLfpStoresResponse: @@ -595,6 +741,7 @@ def __call__( http_options = ( _BaseLfpStoreServiceRestTransport._BaseListLfpStores._get_http_options() ) + request, metadata = self._interceptor.pre_list_lfp_stores(request, metadata) transcoded_request = _BaseLfpStoreServiceRestTransport._BaseListLfpStores._get_transcoded_request( http_options, request @@ -605,6 +752,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.shopping.merchant.lfp_v1beta.LfpStoreServiceClient.ListLfpStores", + extra={ + "serviceName": "google.shopping.merchant.lfp.v1beta.LfpStoreService", + "rpcName": "ListLfpStores", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = LfpStoreServiceRestTransport._ListLfpStores._get_response( self._host, @@ -625,7 +799,29 @@ def __call__( pb_resp = lfpstore.ListLfpStoresResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_lfp_stores(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = lfpstore.ListLfpStoresResponse.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.shopping.merchant.lfp_v1beta.LfpStoreServiceClient.list_lfp_stores", + extra={ + "serviceName": "google.shopping.merchant.lfp.v1beta.LfpStoreService", + "rpcName": "ListLfpStores", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-lfp/samples/generated_samples/snippet_metadata_google.shopping.merchant.lfp.v1beta.json b/packages/google-shopping-merchant-lfp/samples/generated_samples/snippet_metadata_google.shopping.merchant.lfp.v1beta.json index e54573affeba..c88051dded42 100644 --- a/packages/google-shopping-merchant-lfp/samples/generated_samples/snippet_metadata_google.shopping.merchant.lfp.v1beta.json +++ b/packages/google-shopping-merchant-lfp/samples/generated_samples/snippet_metadata_google.shopping.merchant.lfp.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-shopping-merchant-lfp", - "version": "0.1.5" + "version": "0.1.0" }, "snippets": [ { @@ -43,7 +43,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_lfp_v1beta.types.LfpInventory", @@ -119,7 +119,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_lfp_v1beta.types.LfpInventory", @@ -196,7 +196,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_lfp_v1beta.types.LfpSale", @@ -272,7 +272,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_lfp_v1beta.types.LfpSale", @@ -353,7 +353,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_lfp_store" @@ -430,7 +430,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_lfp_store" @@ -508,7 +508,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_lfp_v1beta.types.LfpStore", @@ -588,7 +588,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_lfp_v1beta.types.LfpStore", @@ -673,7 +673,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_lfp_v1beta.types.LfpStore", @@ -757,7 +757,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_lfp_v1beta.types.LfpStore", @@ -838,7 +838,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_lfp_v1beta.services.lfp_store_service.pagers.ListLfpStoresAsyncPager", @@ -918,7 +918,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_lfp_v1beta.services.lfp_store_service.pagers.ListLfpStoresPager", diff --git a/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_inventory_service.py b/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_inventory_service.py index 61cd7852171e..b5cd41e83d0e 100644 --- a/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_inventory_service.py +++ b/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_inventory_service.py @@ -1527,6 +1527,7 @@ def test_insert_lfp_inventory_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.insert_lfp_inventory(request) @@ -1763,6 +1764,7 @@ def test_insert_lfp_inventory_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.insert_lfp_inventory(request) @@ -1892,6 +1894,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.insert_lfp_inventory(request) # Establish that the response is the type that we expect. @@ -1943,6 +1946,7 @@ def test_insert_lfp_inventory_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 = lfpinventory.LfpInventory.to_json(lfpinventory.LfpInventory()) req.return_value.content = return_value diff --git a/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_sale_service.py b/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_sale_service.py index 8f7272454743..4e59cae51f72 100644 --- a/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_sale_service.py +++ b/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_sale_service.py @@ -1443,6 +1443,7 @@ def test_insert_lfp_sale_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.insert_lfp_sale(request) @@ -1671,6 +1672,7 @@ def test_insert_lfp_sale_rest_bad_request(request_type=lfpsale.InsertLfpSaleRequ 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.insert_lfp_sale(request) @@ -1796,6 +1798,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.insert_lfp_sale(request) # Establish that the response is the type that we expect. @@ -1843,6 +1846,7 @@ def test_insert_lfp_sale_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 = lfpsale.LfpSale.to_json(lfpsale.LfpSale()) req.return_value.content = return_value diff --git a/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_store_service.py b/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_store_service.py index 4942ba55ec06..69f3e26da8b8 100644 --- a/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_store_service.py +++ b/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_store_service.py @@ -2758,6 +2758,7 @@ def test_get_lfp_store_rest_required_fields(request_type=lfpstore.GetLfpStoreReq 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_lfp_store(request) @@ -2803,6 +2804,7 @@ def test_get_lfp_store_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_lfp_store(**mock_args) @@ -2936,6 +2938,7 @@ def test_insert_lfp_store_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.insert_lfp_store(request) @@ -2990,6 +2993,7 @@ def test_insert_lfp_store_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.insert_lfp_store(**mock_args) @@ -3121,6 +3125,7 @@ def test_delete_lfp_store_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_lfp_store(request) @@ -3164,6 +3169,7 @@ def test_delete_lfp_store_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_lfp_store(**mock_args) @@ -3309,6 +3315,7 @@ def test_list_lfp_stores_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_lfp_stores(request) @@ -3374,6 +3381,7 @@ def test_list_lfp_stores_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_lfp_stores(**mock_args) @@ -3817,6 +3825,7 @@ def test_get_lfp_store_rest_bad_request(request_type=lfpstore.GetLfpStoreRequest 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_lfp_store(request) @@ -3862,6 +3871,7 @@ def test_get_lfp_store_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_lfp_store(request) # Establish that the response is the type that we expect. @@ -3913,6 +3923,7 @@ def test_get_lfp_store_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 = lfpstore.LfpStore.to_json(lfpstore.LfpStore()) req.return_value.content = return_value @@ -3955,6 +3966,7 @@ def test_insert_lfp_store_rest_bad_request(request_type=lfpstore.InsertLfpStoreR 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.insert_lfp_store(request) @@ -4080,6 +4092,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.insert_lfp_store(request) # Establish that the response is the type that we expect. @@ -4131,6 +4144,7 @@ def test_insert_lfp_store_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 = lfpstore.LfpStore.to_json(lfpstore.LfpStore()) req.return_value.content = return_value @@ -4173,6 +4187,7 @@ def test_delete_lfp_store_rest_bad_request(request_type=lfpstore.DeleteLfpStoreR 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_lfp_store(request) @@ -4203,6 +4218,7 @@ def test_delete_lfp_store_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_lfp_store(request) # Establish that the response is the type that we expect. @@ -4237,6 +4253,7 @@ def test_delete_lfp_store_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 = lfpstore.DeleteLfpStoreRequest() metadata = [ @@ -4275,6 +4292,7 @@ def test_list_lfp_stores_rest_bad_request(request_type=lfpstore.ListLfpStoresReq 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_lfp_stores(request) @@ -4310,6 +4328,7 @@ def test_list_lfp_stores_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_lfp_stores(request) # Establish that the response is the type that we expect. @@ -4348,6 +4367,7 @@ def test_list_lfp_stores_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 = lfpstore.ListLfpStoresResponse.to_json( lfpstore.ListLfpStoresResponse() ) diff --git a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications/gapic_version.py b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications/gapic_version.py index 937ede8823ef..558c8aab67c5 100644 --- a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications/gapic_version.py +++ b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.4" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/gapic_version.py b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/gapic_version.py index 937ede8823ef..558c8aab67c5 100644 --- a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/gapic_version.py +++ b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.4" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/async_client.py b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/async_client.py index f9dd01b3f3df..3ef11b63724d 100644 --- a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/async_client.py +++ b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -55,6 +56,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, NotificationsApiServiceTransport from .transports.grpc_asyncio import NotificationsApiServiceGrpcAsyncIOTransport +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 NotificationsApiServiceAsyncClient: """Service to manage notification subscriptions for merchants""" @@ -274,6 +284,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.shopping.merchant.notifications_v1beta.NotificationsApiServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.notifications.v1beta.NotificationsApiService", + "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.shopping.merchant.notifications.v1beta.NotificationsApiService", + "credentialsType": None, + }, + ) + async def get_notification_subscription( self, request: Optional[ @@ -283,7 +315,7 @@ async def get_notification_subscription( 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]]] = (), ) -> notificationsapi.NotificationSubscription: r"""Gets notification subscriptions for an account. @@ -325,8 +357,10 @@ async def sample_get_notification_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.shopping.merchant_notifications_v1beta.types.NotificationSubscription: @@ -393,7 +427,7 @@ async def create_notification_subscription( ] = 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]]] = (), ) -> notificationsapi.NotificationSubscription: r"""Creates a notification subscription for a merchant. We will allow the following types of notification @@ -466,8 +500,10 @@ async def sample_create_notification_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.shopping.merchant_notifications_v1beta.types.NotificationSubscription: @@ -538,7 +574,7 @@ async def update_notification_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]]] = (), ) -> notificationsapi.NotificationSubscription: r"""Updates an existing notification subscription for a merchant. @@ -592,8 +628,10 @@ async def sample_update_notification_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.shopping.merchant_notifications_v1beta.types.NotificationSubscription: @@ -668,7 +706,7 @@ async def delete_notification_subscription( 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 notification subscription for a merchant. @@ -709,8 +747,10 @@ async def sample_delete_notification_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 @@ -766,7 +806,7 @@ async def list_notification_subscriptions( 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.ListNotificationSubscriptionsAsyncPager: r"""Gets all the notification subscriptions for a merchant. @@ -812,8 +852,10 @@ async def sample_list_notification_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.shopping.merchant_notifications_v1beta.services.notifications_api_service.pagers.ListNotificationSubscriptionsAsyncPager: diff --git a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/client.py b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/client.py index 17c59d6fc6a0..a19c1a2b6a62 100644 --- a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/client.py +++ b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -50,6 +51,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.protobuf import field_mask_pb2 # type: ignore from google.shopping.merchant_notifications_v1beta.services.notifications_api_service import ( @@ -590,6 +600,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( @@ -656,6 +670,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.shopping.merchant.notifications_v1beta.NotificationsApiServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.notifications.v1beta.NotificationsApiService", + "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.shopping.merchant.notifications.v1beta.NotificationsApiService", + "credentialsType": None, + }, + ) + def get_notification_subscription( self, request: Optional[ @@ -665,7 +702,7 @@ def get_notification_subscription( 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]]] = (), ) -> notificationsapi.NotificationSubscription: r"""Gets notification subscriptions for an account. @@ -707,8 +744,10 @@ def sample_get_notification_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.shopping.merchant_notifications_v1beta.types.NotificationSubscription: @@ -774,7 +813,7 @@ def create_notification_subscription( ] = 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]]] = (), ) -> notificationsapi.NotificationSubscription: r"""Creates a notification subscription for a merchant. We will allow the following types of notification @@ -847,8 +886,10 @@ def sample_create_notification_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.shopping.merchant_notifications_v1beta.types.NotificationSubscription: @@ -918,7 +959,7 @@ def update_notification_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]]] = (), ) -> notificationsapi.NotificationSubscription: r"""Updates an existing notification subscription for a merchant. @@ -972,8 +1013,10 @@ def sample_update_notification_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.shopping.merchant_notifications_v1beta.types.NotificationSubscription: @@ -1047,7 +1090,7 @@ def delete_notification_subscription( 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 notification subscription for a merchant. @@ -1088,8 +1131,10 @@ def sample_delete_notification_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 @@ -1144,7 +1189,7 @@ def list_notification_subscriptions( 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.ListNotificationSubscriptionsPager: r"""Gets all the notification subscriptions for a merchant. @@ -1190,8 +1235,10 @@ def sample_list_notification_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.shopping.merchant_notifications_v1beta.services.notifications_api_service.pagers.ListNotificationSubscriptionsPager: diff --git a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/pagers.py b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/pagers.py index b7ae9fe7a99c..38db2200e582 100644 --- a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/pagers.py +++ b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/pagers.py @@ -67,7 +67,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. @@ -81,8 +81,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 = notificationsapi.ListNotificationSubscriptionsRequest(request) @@ -143,7 +145,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. @@ -157,8 +159,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 = notificationsapi.ListNotificationSubscriptionsRequest(request) diff --git a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/grpc.py b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/grpc.py index 4dbf53f3f4a2..382cdae4c6d0 100644 --- a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/grpc.py +++ b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -21,12 +24,90 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore +import proto # type: ignore from google.shopping.merchant_notifications_v1beta.types import notificationsapi from .base import DEFAULT_CLIENT_INFO, NotificationsApiServiceTransport +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.shopping.merchant.notifications.v1beta.NotificationsApiService", + "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.shopping.merchant.notifications.v1beta.NotificationsApiService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class NotificationsApiServiceGrpcTransport(NotificationsApiServiceTransport): """gRPC backend transport for NotificationsApiService. @@ -180,7 +261,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 @@ -259,7 +345,7 @@ def get_notification_subscription( if "get_notification_subscription" not in self._stubs: self._stubs[ "get_notification_subscription" - ] = self.grpc_channel.unary_unary( + ] = self._logged_channel.unary_unary( "/google.shopping.merchant.notifications.v1beta.NotificationsApiService/GetNotificationSubscription", request_serializer=notificationsapi.GetNotificationSubscriptionRequest.serialize, response_deserializer=notificationsapi.NotificationSubscription.deserialize, @@ -308,7 +394,7 @@ def create_notification_subscription( if "create_notification_subscription" not in self._stubs: self._stubs[ "create_notification_subscription" - ] = self.grpc_channel.unary_unary( + ] = self._logged_channel.unary_unary( "/google.shopping.merchant.notifications.v1beta.NotificationsApiService/CreateNotificationSubscription", request_serializer=notificationsapi.CreateNotificationSubscriptionRequest.serialize, response_deserializer=notificationsapi.NotificationSubscription.deserialize, @@ -341,7 +427,7 @@ def update_notification_subscription( if "update_notification_subscription" not in self._stubs: self._stubs[ "update_notification_subscription" - ] = self.grpc_channel.unary_unary( + ] = self._logged_channel.unary_unary( "/google.shopping.merchant.notifications.v1beta.NotificationsApiService/UpdateNotificationSubscription", request_serializer=notificationsapi.UpdateNotificationSubscriptionRequest.serialize, response_deserializer=notificationsapi.NotificationSubscription.deserialize, @@ -372,7 +458,7 @@ def delete_notification_subscription( if "delete_notification_subscription" not in self._stubs: self._stubs[ "delete_notification_subscription" - ] = self.grpc_channel.unary_unary( + ] = self._logged_channel.unary_unary( "/google.shopping.merchant.notifications.v1beta.NotificationsApiService/DeleteNotificationSubscription", request_serializer=notificationsapi.DeleteNotificationSubscriptionRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -405,7 +491,7 @@ def list_notification_subscriptions( if "list_notification_subscriptions" not in self._stubs: self._stubs[ "list_notification_subscriptions" - ] = self.grpc_channel.unary_unary( + ] = self._logged_channel.unary_unary( "/google.shopping.merchant.notifications.v1beta.NotificationsApiService/ListNotificationSubscriptions", request_serializer=notificationsapi.ListNotificationSubscriptionsRequest.serialize, response_deserializer=notificationsapi.ListNotificationSubscriptionsResponse.deserialize, @@ -413,7 +499,7 @@ def list_notification_subscriptions( return self._stubs["list_notification_subscriptions"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/grpc_asyncio.py index fce42dccdbf0..141c6502c858 100644 --- a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -23,14 +26,93 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_notifications_v1beta.types import notificationsapi from .base import DEFAULT_CLIENT_INFO, NotificationsApiServiceTransport from .grpc import NotificationsApiServiceGrpcTransport +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.shopping.merchant.notifications.v1beta.NotificationsApiService", + "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.shopping.merchant.notifications.v1beta.NotificationsApiService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class NotificationsApiServiceGrpcAsyncIOTransport(NotificationsApiServiceTransport): """gRPC AsyncIO backend transport for NotificationsApiService. @@ -227,10 +309,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 @@ -267,7 +352,7 @@ def get_notification_subscription( if "get_notification_subscription" not in self._stubs: self._stubs[ "get_notification_subscription" - ] = self.grpc_channel.unary_unary( + ] = self._logged_channel.unary_unary( "/google.shopping.merchant.notifications.v1beta.NotificationsApiService/GetNotificationSubscription", request_serializer=notificationsapi.GetNotificationSubscriptionRequest.serialize, response_deserializer=notificationsapi.NotificationSubscription.deserialize, @@ -316,7 +401,7 @@ def create_notification_subscription( if "create_notification_subscription" not in self._stubs: self._stubs[ "create_notification_subscription" - ] = self.grpc_channel.unary_unary( + ] = self._logged_channel.unary_unary( "/google.shopping.merchant.notifications.v1beta.NotificationsApiService/CreateNotificationSubscription", request_serializer=notificationsapi.CreateNotificationSubscriptionRequest.serialize, response_deserializer=notificationsapi.NotificationSubscription.deserialize, @@ -349,7 +434,7 @@ def update_notification_subscription( if "update_notification_subscription" not in self._stubs: self._stubs[ "update_notification_subscription" - ] = self.grpc_channel.unary_unary( + ] = self._logged_channel.unary_unary( "/google.shopping.merchant.notifications.v1beta.NotificationsApiService/UpdateNotificationSubscription", request_serializer=notificationsapi.UpdateNotificationSubscriptionRequest.serialize, response_deserializer=notificationsapi.NotificationSubscription.deserialize, @@ -381,7 +466,7 @@ def delete_notification_subscription( if "delete_notification_subscription" not in self._stubs: self._stubs[ "delete_notification_subscription" - ] = self.grpc_channel.unary_unary( + ] = self._logged_channel.unary_unary( "/google.shopping.merchant.notifications.v1beta.NotificationsApiService/DeleteNotificationSubscription", request_serializer=notificationsapi.DeleteNotificationSubscriptionRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -414,7 +499,7 @@ def list_notification_subscriptions( if "list_notification_subscriptions" not in self._stubs: self._stubs[ "list_notification_subscriptions" - ] = self.grpc_channel.unary_unary( + ] = self._logged_channel.unary_unary( "/google.shopping.merchant.notifications.v1beta.NotificationsApiService/ListNotificationSubscriptions", request_serializer=notificationsapi.ListNotificationSubscriptionsRequest.serialize, response_deserializer=notificationsapi.ListNotificationSubscriptionsResponse.deserialize, @@ -457,7 +542,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/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/rest.py b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/rest.py index 7c61a8e38280..5eedb5916c07 100644 --- a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/rest.py +++ b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -38,6 +38,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, @@ -106,10 +114,10 @@ def post_update_notification_subscription(self, response): def pre_create_notification_subscription( self, request: notificationsapi.CreateNotificationSubscriptionRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ notificationsapi.CreateNotificationSubscriptionRequest, - Sequence[Tuple[str, str]], + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for create_notification_subscription @@ -132,10 +140,10 @@ def post_create_notification_subscription( def pre_delete_notification_subscription( self, request: notificationsapi.DeleteNotificationSubscriptionRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ notificationsapi.DeleteNotificationSubscriptionRequest, - Sequence[Tuple[str, str]], + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for delete_notification_subscription @@ -147,9 +155,10 @@ def pre_delete_notification_subscription( def pre_get_notification_subscription( self, request: notificationsapi.GetNotificationSubscriptionRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - notificationsapi.GetNotificationSubscriptionRequest, Sequence[Tuple[str, str]] + notificationsapi.GetNotificationSubscriptionRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for get_notification_subscription @@ -172,9 +181,10 @@ def post_get_notification_subscription( def pre_list_notification_subscriptions( self, request: notificationsapi.ListNotificationSubscriptionsRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - notificationsapi.ListNotificationSubscriptionsRequest, Sequence[Tuple[str, str]] + notificationsapi.ListNotificationSubscriptionsRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for list_notification_subscriptions @@ -197,10 +207,10 @@ def post_list_notification_subscriptions( def pre_update_notification_subscription( self, request: notificationsapi.UpdateNotificationSubscriptionRequest, - metadata: Sequence[Tuple[str, str]], + metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ notificationsapi.UpdateNotificationSubscriptionRequest, - Sequence[Tuple[str, str]], + Sequence[Tuple[str, Union[str, bytes]]], ]: """Pre-rpc interceptor for update_notification_subscription @@ -345,7 +355,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]]] = (), ) -> notificationsapi.NotificationSubscription: r"""Call the create notification subscription method over HTTP. @@ -357,8 +367,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: ~.notificationsapi.NotificationSubscription: @@ -371,6 +383,7 @@ def __call__( http_options = ( _BaseNotificationsApiServiceRestTransport._BaseCreateNotificationSubscription._get_http_options() ) + request, metadata = self._interceptor.pre_create_notification_subscription( request, metadata ) @@ -387,6 +400,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.shopping.merchant.notifications_v1beta.NotificationsApiServiceClient.CreateNotificationSubscription", + extra={ + "serviceName": "google.shopping.merchant.notifications.v1beta.NotificationsApiService", + "rpcName": "CreateNotificationSubscription", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = NotificationsApiServiceRestTransport._CreateNotificationSubscription._get_response( self._host, @@ -408,7 +448,31 @@ def __call__( pb_resp = notificationsapi.NotificationSubscription.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_notification_subscription(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + notificationsapi.NotificationSubscription.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.shopping.merchant.notifications_v1beta.NotificationsApiServiceClient.create_notification_subscription", + extra={ + "serviceName": "google.shopping.merchant.notifications.v1beta.NotificationsApiService", + "rpcName": "CreateNotificationSubscription", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _DeleteNotificationSubscription( @@ -448,7 +512,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 notification subscription method over HTTP. @@ -460,13 +524,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 = ( _BaseNotificationsApiServiceRestTransport._BaseDeleteNotificationSubscription._get_http_options() ) + request, metadata = self._interceptor.pre_delete_notification_subscription( request, metadata ) @@ -479,6 +546,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.shopping.merchant.notifications_v1beta.NotificationsApiServiceClient.DeleteNotificationSubscription", + extra={ + "serviceName": "google.shopping.merchant.notifications.v1beta.NotificationsApiService", + "rpcName": "DeleteNotificationSubscription", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = NotificationsApiServiceRestTransport._DeleteNotificationSubscription._get_response( self._host, @@ -531,7 +625,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]]] = (), ) -> notificationsapi.NotificationSubscription: r"""Call the get notification subscription method over HTTP. @@ -543,8 +637,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: ~.notificationsapi.NotificationSubscription: @@ -557,6 +653,7 @@ def __call__( http_options = ( _BaseNotificationsApiServiceRestTransport._BaseGetNotificationSubscription._get_http_options() ) + request, metadata = self._interceptor.pre_get_notification_subscription( request, metadata ) @@ -569,6 +666,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.shopping.merchant.notifications_v1beta.NotificationsApiServiceClient.GetNotificationSubscription", + extra={ + "serviceName": "google.shopping.merchant.notifications.v1beta.NotificationsApiService", + "rpcName": "GetNotificationSubscription", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = NotificationsApiServiceRestTransport._GetNotificationSubscription._get_response( self._host, @@ -589,7 +713,31 @@ def __call__( pb_resp = notificationsapi.NotificationSubscription.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_notification_subscription(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + notificationsapi.NotificationSubscription.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.shopping.merchant.notifications_v1beta.NotificationsApiServiceClient.get_notification_subscription", + extra={ + "serviceName": "google.shopping.merchant.notifications.v1beta.NotificationsApiService", + "rpcName": "GetNotificationSubscription", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListNotificationSubscriptions( @@ -629,7 +777,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]]] = (), ) -> notificationsapi.ListNotificationSubscriptionsResponse: r"""Call the list notification subscriptions method over HTTP. @@ -641,8 +789,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: ~.notificationsapi.ListNotificationSubscriptionsResponse: @@ -654,6 +804,7 @@ def __call__( http_options = ( _BaseNotificationsApiServiceRestTransport._BaseListNotificationSubscriptions._get_http_options() ) + request, metadata = self._interceptor.pre_list_notification_subscriptions( request, metadata ) @@ -666,6 +817,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.shopping.merchant.notifications_v1beta.NotificationsApiServiceClient.ListNotificationSubscriptions", + extra={ + "serviceName": "google.shopping.merchant.notifications.v1beta.NotificationsApiService", + "rpcName": "ListNotificationSubscriptions", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = NotificationsApiServiceRestTransport._ListNotificationSubscriptions._get_response( self._host, @@ -686,7 +864,33 @@ def __call__( pb_resp = notificationsapi.ListNotificationSubscriptionsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_notification_subscriptions(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + notificationsapi.ListNotificationSubscriptionsResponse.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.shopping.merchant.notifications_v1beta.NotificationsApiServiceClient.list_notification_subscriptions", + extra={ + "serviceName": "google.shopping.merchant.notifications.v1beta.NotificationsApiService", + "rpcName": "ListNotificationSubscriptions", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _UpdateNotificationSubscription( @@ -727,7 +931,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]]] = (), ) -> notificationsapi.NotificationSubscription: r"""Call the update notification subscription method over HTTP. @@ -739,8 +943,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: ~.notificationsapi.NotificationSubscription: @@ -753,6 +959,7 @@ def __call__( http_options = ( _BaseNotificationsApiServiceRestTransport._BaseUpdateNotificationSubscription._get_http_options() ) + request, metadata = self._interceptor.pre_update_notification_subscription( request, metadata ) @@ -769,6 +976,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.shopping.merchant.notifications_v1beta.NotificationsApiServiceClient.UpdateNotificationSubscription", + extra={ + "serviceName": "google.shopping.merchant.notifications.v1beta.NotificationsApiService", + "rpcName": "UpdateNotificationSubscription", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = NotificationsApiServiceRestTransport._UpdateNotificationSubscription._get_response( self._host, @@ -790,7 +1024,31 @@ def __call__( pb_resp = notificationsapi.NotificationSubscription.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_notification_subscription(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + notificationsapi.NotificationSubscription.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.shopping.merchant.notifications_v1beta.NotificationsApiServiceClient.update_notification_subscription", + extra={ + "serviceName": "google.shopping.merchant.notifications.v1beta.NotificationsApiService", + "rpcName": "UpdateNotificationSubscription", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-notifications/samples/generated_samples/snippet_metadata_google.shopping.merchant.notifications.v1beta.json b/packages/google-shopping-merchant-notifications/samples/generated_samples/snippet_metadata_google.shopping.merchant.notifications.v1beta.json index 8ef25b049d98..b27b3eb2144a 100644 --- a/packages/google-shopping-merchant-notifications/samples/generated_samples/snippet_metadata_google.shopping.merchant.notifications.v1beta.json +++ b/packages/google-shopping-merchant-notifications/samples/generated_samples/snippet_metadata_google.shopping.merchant.notifications.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-shopping-merchant-notifications", - "version": "0.1.4" + "version": "0.1.0" }, "snippets": [ { @@ -51,7 +51,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_notifications_v1beta.types.NotificationSubscription", @@ -135,7 +135,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_notifications_v1beta.types.NotificationSubscription", @@ -216,7 +216,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_notification_subscription" @@ -293,7 +293,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_notification_subscription" @@ -371,7 +371,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_notifications_v1beta.types.NotificationSubscription", @@ -451,7 +451,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_notifications_v1beta.types.NotificationSubscription", @@ -532,7 +532,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_notifications_v1beta.services.notifications_api_service.pagers.ListNotificationSubscriptionsAsyncPager", @@ -612,7 +612,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_notifications_v1beta.services.notifications_api_service.pagers.ListNotificationSubscriptionsPager", @@ -697,7 +697,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_notifications_v1beta.types.NotificationSubscription", @@ -781,7 +781,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_notifications_v1beta.types.NotificationSubscription", diff --git a/packages/google-shopping-merchant-notifications/tests/unit/gapic/merchant_notifications_v1beta/test_notifications_api_service.py b/packages/google-shopping-merchant-notifications/tests/unit/gapic/merchant_notifications_v1beta/test_notifications_api_service.py index 539113224bb4..4c80bffc3327 100644 --- a/packages/google-shopping-merchant-notifications/tests/unit/gapic/merchant_notifications_v1beta/test_notifications_api_service.py +++ b/packages/google-shopping-merchant-notifications/tests/unit/gapic/merchant_notifications_v1beta/test_notifications_api_service.py @@ -3222,6 +3222,7 @@ def test_get_notification_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_notification_subscription(request) @@ -3269,6 +3270,7 @@ def test_get_notification_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_notification_subscription(**mock_args) @@ -3406,6 +3408,7 @@ def test_create_notification_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.create_notification_subscription(request) @@ -3464,6 +3467,7 @@ def test_create_notification_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_notification_subscription(**mock_args) @@ -3601,6 +3605,7 @@ def test_update_notification_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_notification_subscription(request) @@ -3657,6 +3662,7 @@ def test_update_notification_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_notification_subscription(**mock_args) @@ -3793,6 +3799,7 @@ def test_delete_notification_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_notification_subscription(request) @@ -3838,6 +3845,7 @@ def test_delete_notification_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_notification_subscription(**mock_args) @@ -3983,6 +3991,7 @@ def test_list_notification_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_notification_subscriptions(request) @@ -4040,6 +4049,7 @@ def test_list_notification_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_notification_subscriptions(**mock_args) @@ -4547,6 +4557,7 @@ def test_get_notification_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.get_notification_subscription(request) @@ -4585,6 +4596,7 @@ def test_get_notification_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_notification_subscription(request) # Establish that the response is the type that we expect. @@ -4632,6 +4644,7 @@ def test_get_notification_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 = notificationsapi.NotificationSubscription.to_json( notificationsapi.NotificationSubscription() ) @@ -4678,6 +4691,7 @@ def test_create_notification_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.create_notification_subscription(request) @@ -4796,6 +4810,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_notification_subscription(request) # Establish that the response is the type that we expect. @@ -4843,6 +4858,7 @@ def test_create_notification_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 = notificationsapi.NotificationSubscription.to_json( notificationsapi.NotificationSubscription() ) @@ -4893,6 +4909,7 @@ def test_update_notification_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_notification_subscription(request) @@ -5015,6 +5032,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.update_notification_subscription(request) # Establish that the response is the type that we expect. @@ -5062,6 +5080,7 @@ def test_update_notification_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 = notificationsapi.NotificationSubscription.to_json( notificationsapi.NotificationSubscription() ) @@ -5108,6 +5127,7 @@ def test_delete_notification_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_notification_subscription(request) @@ -5138,6 +5158,7 @@ def test_delete_notification_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_notification_subscription(request) # Establish that the response is the type that we expect. @@ -5175,6 +5196,7 @@ def test_delete_notification_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 = notificationsapi.DeleteNotificationSubscriptionRequest() metadata = [ @@ -5215,6 +5237,7 @@ def test_list_notification_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_notification_subscriptions(request) @@ -5252,6 +5275,7 @@ def test_list_notification_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_notification_subscriptions(request) # Establish that the response is the type that we expect. @@ -5294,6 +5318,7 @@ def test_list_notification_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 = notificationsapi.ListNotificationSubscriptionsResponse.to_json( notificationsapi.ListNotificationSubscriptionsResponse() ) diff --git a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions/gapic_version.py b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions/gapic_version.py index 937ede8823ef..558c8aab67c5 100644 --- a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions/gapic_version.py +++ b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.4" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/gapic_version.py b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/gapic_version.py index 937ede8823ef..558c8aab67c5 100644 --- a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/gapic_version.py +++ b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.4" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/async_client.py b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/async_client.py index 70670bb806fb..6a80990a8530 100644 --- a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/async_client.py +++ b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -56,6 +57,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, PromotionsServiceTransport from .transports.grpc_asyncio import PromotionsServiceGrpcAsyncIOTransport +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 PromotionsServiceAsyncClient: """Service to manage promotions for products.""" @@ -265,13 +275,35 @@ def __init__( client_info=client_info, ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.shopping.merchant.promotions_v1beta.PromotionsServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.promotions.v1beta.PromotionsService", + "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.shopping.merchant.promotions.v1beta.PromotionsService", + "credentialsType": None, + }, + ) + async def insert_promotion( self, request: Optional[Union[promotions.InsertPromotionRequest, dict]] = 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]]] = (), ) -> promotions.Promotion: r"""Inserts a promotion for your Merchant Center account. If the promotion already exists, then it updates the @@ -317,8 +349,10 @@ async def sample_insert_promotion(): 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.shopping.merchant_promotions_v1beta.types.Promotion: @@ -377,7 +411,7 @@ async def get_promotion( 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]]] = (), ) -> promotions.Promotion: r"""Retrieves the promotion from your Merchant Center account. @@ -424,8 +458,10 @@ async def sample_get_promotion(): 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.shopping.merchant_promotions_v1beta.types.Promotion: @@ -498,7 +534,7 @@ async def list_promotions( 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.ListPromotionsAsyncPager: r"""Lists the promotions in your Merchant Center account. The response might contain fewer items than specified by @@ -548,8 +584,10 @@ async def sample_list_promotions(): 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.shopping.merchant_promotions_v1beta.services.promotions_service.pagers.ListPromotionsAsyncPager: diff --git a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/client.py b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/client.py index bd9a6634ccab..c589b0e7f7a0 100644 --- a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/client.py +++ b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.shopping.type.types import types from google.shopping.merchant_promotions_v1beta.services.promotions_service import ( @@ -584,6 +594,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( @@ -650,13 +664,36 @@ 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.shopping.merchant.promotions_v1beta.PromotionsServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.promotions.v1beta.PromotionsService", + "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.shopping.merchant.promotions.v1beta.PromotionsService", + "credentialsType": None, + }, + ) + def insert_promotion( self, request: Optional[Union[promotions.InsertPromotionRequest, dict]] = 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]]] = (), ) -> promotions.Promotion: r"""Inserts a promotion for your Merchant Center account. If the promotion already exists, then it updates the @@ -702,8 +739,10 @@ def sample_insert_promotion(): 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.shopping.merchant_promotions_v1beta.types.Promotion: @@ -760,7 +799,7 @@ def get_promotion( 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]]] = (), ) -> promotions.Promotion: r"""Retrieves the promotion from your Merchant Center account. @@ -807,8 +846,10 @@ def sample_get_promotion(): 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.shopping.merchant_promotions_v1beta.types.Promotion: @@ -878,7 +919,7 @@ def list_promotions( 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.ListPromotionsPager: r"""Lists the promotions in your Merchant Center account. The response might contain fewer items than specified by @@ -928,8 +969,10 @@ def sample_list_promotions(): 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.shopping.merchant_promotions_v1beta.services.promotions_service.pagers.ListPromotionsPager: diff --git a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/pagers.py b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/pagers.py index cdcafe41830b..87b1030c4243 100644 --- a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/pagers.py +++ b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/pagers.py @@ -67,7 +67,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. @@ -81,8 +81,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 = promotions.ListPromotionsRequest(request) @@ -141,7 +143,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. @@ -155,8 +157,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 = promotions.ListPromotionsRequest(request) diff --git a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc.py b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc.py index c60167c4515f..ea7eea1058af 100644 --- a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc.py +++ b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -20,12 +23,90 @@ 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.shopping.merchant_promotions_v1beta.types import promotions from .base import DEFAULT_CLIENT_INFO, PromotionsServiceTransport +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.shopping.merchant.promotions.v1beta.PromotionsService", + "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.shopping.merchant.promotions.v1beta.PromotionsService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class PromotionsServiceGrpcTransport(PromotionsServiceTransport): """gRPC backend transport for PromotionsService. @@ -179,7 +260,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 @@ -255,7 +341,7 @@ def insert_promotion( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "insert_promotion" not in self._stubs: - self._stubs["insert_promotion"] = self.grpc_channel.unary_unary( + self._stubs["insert_promotion"] = self._logged_channel.unary_unary( "/google.shopping.merchant.promotions.v1beta.PromotionsService/InsertPromotion", request_serializer=promotions.InsertPromotionRequest.serialize, response_deserializer=promotions.Promotion.deserialize, @@ -285,7 +371,7 @@ def get_promotion( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_promotion" not in self._stubs: - self._stubs["get_promotion"] = self.grpc_channel.unary_unary( + self._stubs["get_promotion"] = self._logged_channel.unary_unary( "/google.shopping.merchant.promotions.v1beta.PromotionsService/GetPromotion", request_serializer=promotions.GetPromotionRequest.serialize, response_deserializer=promotions.Promotion.deserialize, @@ -319,7 +405,7 @@ def list_promotions( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_promotions" not in self._stubs: - self._stubs["list_promotions"] = self.grpc_channel.unary_unary( + self._stubs["list_promotions"] = self._logged_channel.unary_unary( "/google.shopping.merchant.promotions.v1beta.PromotionsService/ListPromotions", request_serializer=promotions.ListPromotionsRequest.serialize, response_deserializer=promotions.ListPromotionsResponse.deserialize, @@ -327,7 +413,7 @@ def list_promotions( return self._stubs["list_promotions"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc_asyncio.py index 75776592ea82..8f428255c35c 100644 --- a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -22,14 +25,93 @@ 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 from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_promotions_v1beta.types import promotions from .base import DEFAULT_CLIENT_INFO, PromotionsServiceTransport from .grpc import PromotionsServiceGrpcTransport +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.shopping.merchant.promotions.v1beta.PromotionsService", + "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.shopping.merchant.promotions.v1beta.PromotionsService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class PromotionsServiceGrpcAsyncIOTransport(PromotionsServiceTransport): """gRPC AsyncIO backend transport for PromotionsService. @@ -226,10 +308,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 @@ -263,7 +348,7 @@ def insert_promotion( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "insert_promotion" not in self._stubs: - self._stubs["insert_promotion"] = self.grpc_channel.unary_unary( + self._stubs["insert_promotion"] = self._logged_channel.unary_unary( "/google.shopping.merchant.promotions.v1beta.PromotionsService/InsertPromotion", request_serializer=promotions.InsertPromotionRequest.serialize, response_deserializer=promotions.Promotion.deserialize, @@ -293,7 +378,7 @@ def get_promotion( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_promotion" not in self._stubs: - self._stubs["get_promotion"] = self.grpc_channel.unary_unary( + self._stubs["get_promotion"] = self._logged_channel.unary_unary( "/google.shopping.merchant.promotions.v1beta.PromotionsService/GetPromotion", request_serializer=promotions.GetPromotionRequest.serialize, response_deserializer=promotions.Promotion.deserialize, @@ -327,7 +412,7 @@ def list_promotions( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_promotions" not in self._stubs: - self._stubs["list_promotions"] = self.grpc_channel.unary_unary( + self._stubs["list_promotions"] = self._logged_channel.unary_unary( "/google.shopping.merchant.promotions.v1beta.PromotionsService/ListPromotions", request_serializer=promotions.ListPromotionsRequest.serialize, response_deserializer=promotions.ListPromotionsResponse.deserialize, @@ -360,7 +445,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/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest.py b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest.py index efd1401a514c..1cea05241158 100644 --- a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest.py +++ b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -37,6 +37,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, @@ -93,8 +101,8 @@ def post_list_promotions(self, response): def pre_get_promotion( self, request: promotions.GetPromotionRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[promotions.GetPromotionRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[promotions.GetPromotionRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for get_promotion Override in a subclass to manipulate the request or metadata @@ -116,8 +124,10 @@ def post_get_promotion( def pre_insert_promotion( self, request: promotions.InsertPromotionRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[promotions.InsertPromotionRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + promotions.InsertPromotionRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for insert_promotion Override in a subclass to manipulate the request or metadata @@ -139,8 +149,10 @@ def post_insert_promotion( def pre_list_promotions( self, request: promotions.ListPromotionsRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[promotions.ListPromotionsRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + promotions.ListPromotionsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for list_promotions Override in a subclass to manipulate the request or metadata @@ -280,7 +292,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]]] = (), ) -> promotions.Promotion: r"""Call the get promotion method over HTTP. @@ -290,8 +302,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: ~.promotions.Promotion: @@ -315,6 +329,7 @@ def __call__( http_options = ( _BasePromotionsServiceRestTransport._BaseGetPromotion._get_http_options() ) + request, metadata = self._interceptor.pre_get_promotion(request, metadata) transcoded_request = _BasePromotionsServiceRestTransport._BaseGetPromotion._get_transcoded_request( http_options, request @@ -325,6 +340,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.shopping.merchant.promotions_v1beta.PromotionsServiceClient.GetPromotion", + extra={ + "serviceName": "google.shopping.merchant.promotions.v1beta.PromotionsService", + "rpcName": "GetPromotion", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = PromotionsServiceRestTransport._GetPromotion._get_response( self._host, @@ -345,7 +387,29 @@ def __call__( pb_resp = promotions.Promotion.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_promotion(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = promotions.Promotion.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.shopping.merchant.promotions_v1beta.PromotionsServiceClient.get_promotion", + extra={ + "serviceName": "google.shopping.merchant.promotions.v1beta.PromotionsService", + "rpcName": "GetPromotion", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _InsertPromotion( @@ -384,7 +448,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]]] = (), ) -> promotions.Promotion: r"""Call the insert promotion method over HTTP. @@ -394,8 +458,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: ~.promotions.Promotion: @@ -419,6 +485,7 @@ def __call__( http_options = ( _BasePromotionsServiceRestTransport._BaseInsertPromotion._get_http_options() ) + request, metadata = self._interceptor.pre_insert_promotion( request, metadata ) @@ -435,6 +502,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.shopping.merchant.promotions_v1beta.PromotionsServiceClient.InsertPromotion", + extra={ + "serviceName": "google.shopping.merchant.promotions.v1beta.PromotionsService", + "rpcName": "InsertPromotion", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = PromotionsServiceRestTransport._InsertPromotion._get_response( self._host, @@ -456,7 +550,29 @@ def __call__( pb_resp = promotions.Promotion.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_insert_promotion(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = promotions.Promotion.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.shopping.merchant.promotions_v1beta.PromotionsServiceClient.insert_promotion", + extra={ + "serviceName": "google.shopping.merchant.promotions.v1beta.PromotionsService", + "rpcName": "InsertPromotion", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListPromotions( @@ -494,7 +610,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]]] = (), ) -> promotions.ListPromotionsResponse: r"""Call the list promotions method over HTTP. @@ -504,8 +620,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: ~.promotions.ListPromotionsResponse: @@ -515,6 +633,7 @@ def __call__( http_options = ( _BasePromotionsServiceRestTransport._BaseListPromotions._get_http_options() ) + request, metadata = self._interceptor.pre_list_promotions(request, metadata) transcoded_request = _BasePromotionsServiceRestTransport._BaseListPromotions._get_transcoded_request( http_options, request @@ -525,6 +644,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.shopping.merchant.promotions_v1beta.PromotionsServiceClient.ListPromotions", + extra={ + "serviceName": "google.shopping.merchant.promotions.v1beta.PromotionsService", + "rpcName": "ListPromotions", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = PromotionsServiceRestTransport._ListPromotions._get_response( self._host, @@ -545,7 +691,31 @@ def __call__( pb_resp = promotions.ListPromotionsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_promotions(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = promotions.ListPromotionsResponse.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.shopping.merchant.promotions_v1beta.PromotionsServiceClient.list_promotions", + extra={ + "serviceName": "google.shopping.merchant.promotions.v1beta.PromotionsService", + "rpcName": "ListPromotions", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-promotions/samples/generated_samples/snippet_metadata_google.shopping.merchant.promotions.v1beta.json b/packages/google-shopping-merchant-promotions/samples/generated_samples/snippet_metadata_google.shopping.merchant.promotions.v1beta.json index d0f8cb6bfc9d..35c4091b4ca2 100644 --- a/packages/google-shopping-merchant-promotions/samples/generated_samples/snippet_metadata_google.shopping.merchant.promotions.v1beta.json +++ b/packages/google-shopping-merchant-promotions/samples/generated_samples/snippet_metadata_google.shopping.merchant.promotions.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-shopping-merchant-promotions", - "version": "0.1.4" + "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.shopping.merchant_promotions_v1beta.types.Promotion", @@ -127,7 +127,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_promotions_v1beta.types.Promotion", @@ -204,7 +204,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_promotions_v1beta.types.Promotion", @@ -280,7 +280,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_promotions_v1beta.types.Promotion", @@ -361,7 +361,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_promotions_v1beta.services.promotions_service.pagers.ListPromotionsAsyncPager", @@ -441,7 +441,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_promotions_v1beta.services.promotions_service.pagers.ListPromotionsPager", diff --git a/packages/google-shopping-merchant-promotions/tests/unit/gapic/merchant_promotions_v1beta/test_promotions_service.py b/packages/google-shopping-merchant-promotions/tests/unit/gapic/merchant_promotions_v1beta/test_promotions_service.py index d04c440dbc01..f103f5757a16 100644 --- a/packages/google-shopping-merchant-promotions/tests/unit/gapic/merchant_promotions_v1beta/test_promotions_service.py +++ b/packages/google-shopping-merchant-promotions/tests/unit/gapic/merchant_promotions_v1beta/test_promotions_service.py @@ -2348,6 +2348,7 @@ def test_insert_promotion_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.insert_promotion(request) @@ -2476,6 +2477,7 @@ def test_get_promotion_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_promotion(request) @@ -2521,6 +2523,7 @@ def test_get_promotion_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_promotion(**mock_args) @@ -2659,6 +2662,7 @@ def test_list_promotions_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_promotions(request) @@ -2712,6 +2716,7 @@ def test_list_promotions_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_promotions(**mock_args) @@ -3106,6 +3111,7 @@ def test_insert_promotion_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.insert_promotion(request) @@ -3147,6 +3153,7 @@ def test_insert_promotion_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.insert_promotion(request) # Establish that the response is the type that we expect. @@ -3193,6 +3200,7 @@ def test_insert_promotion_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 = promotions.Promotion.to_json(promotions.Promotion()) req.return_value.content = return_value @@ -3235,6 +3243,7 @@ def test_get_promotion_rest_bad_request(request_type=promotions.GetPromotionRequ 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_promotion(request) @@ -3276,6 +3285,7 @@ def test_get_promotion_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_promotion(request) # Establish that the response is the type that we expect. @@ -3320,6 +3330,7 @@ def test_get_promotion_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 = promotions.Promotion.to_json(promotions.Promotion()) req.return_value.content = return_value @@ -3364,6 +3375,7 @@ def test_list_promotions_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_promotions(request) @@ -3399,6 +3411,7 @@ def test_list_promotions_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_promotions(request) # Establish that the response is the type that we expect. @@ -3439,6 +3452,7 @@ def test_list_promotions_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 = promotions.ListPromotionsResponse.to_json( promotions.ListPromotionsResponse() ) diff --git a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota/gapic_version.py b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota/gapic_version.py index 937ede8823ef..558c8aab67c5 100644 --- a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota/gapic_version.py +++ b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.4" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/gapic_version.py b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/gapic_version.py index 937ede8823ef..558c8aab67c5 100644 --- a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/gapic_version.py +++ b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.4" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/async_client.py b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/async_client.py index 3e89516cd556..18514ce5acb6 100644 --- a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/async_client.py +++ b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -49,6 +50,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, QuotaServiceTransport from .transports.grpc_asyncio import QuotaServiceGrpcAsyncIOTransport +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 QuotaServiceAsyncClient: """Service to get method call quota information per Merchant API @@ -252,6 +262,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.shopping.merchant.quota_v1beta.QuotaServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.quota.v1beta.QuotaService", + "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.shopping.merchant.quota.v1beta.QuotaService", + "credentialsType": None, + }, + ) + async def list_quota_groups( self, request: Optional[Union[quota.ListQuotaGroupsRequest, dict]] = None, @@ -259,7 +291,7 @@ async def list_quota_groups( 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.ListQuotaGroupsAsyncPager: r"""Lists the daily call quota and usage per group for your Merchant Center account. @@ -306,8 +338,10 @@ async def sample_list_quota_groups(): 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.shopping.merchant_quota_v1beta.services.quota_service.pagers.ListQuotaGroupsAsyncPager: diff --git a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/client.py b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/client.py index b590cbd9bf64..ef3f0a2b9e34 100644 --- a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/client.py +++ b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.shopping.merchant_quota_v1beta.services.quota_service import pagers from google.shopping.merchant_quota_v1beta.types import quota @@ -573,6 +583,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( @@ -635,6 +649,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.shopping.merchant.quota_v1beta.QuotaServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.quota.v1beta.QuotaService", + "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.shopping.merchant.quota.v1beta.QuotaService", + "credentialsType": None, + }, + ) + def list_quota_groups( self, request: Optional[Union[quota.ListQuotaGroupsRequest, dict]] = None, @@ -642,7 +679,7 @@ def list_quota_groups( 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.ListQuotaGroupsPager: r"""Lists the daily call quota and usage per group for your Merchant Center account. @@ -689,8 +726,10 @@ def sample_list_quota_groups(): 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.shopping.merchant_quota_v1beta.services.quota_service.pagers.ListQuotaGroupsPager: diff --git a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/pagers.py b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/pagers.py index fcb1ce134f0d..5359d0205a80 100644 --- a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/pagers.py +++ b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/pagers.py @@ -67,7 +67,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. @@ -81,8 +81,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 = quota.ListQuotaGroupsRequest(request) @@ -141,7 +143,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. @@ -155,8 +157,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 = quota.ListQuotaGroupsRequest(request) diff --git a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc.py b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc.py index 99b13679bca4..2f50b1db9685 100644 --- a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc.py +++ b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -20,12 +23,90 @@ 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.shopping.merchant_quota_v1beta.types import quota from .base import DEFAULT_CLIENT_INFO, QuotaServiceTransport +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.shopping.merchant.quota.v1beta.QuotaService", + "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.shopping.merchant.quota.v1beta.QuotaService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class QuotaServiceGrpcTransport(QuotaServiceTransport): """gRPC backend transport for QuotaService. @@ -180,7 +261,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 @@ -255,7 +341,7 @@ def list_quota_groups( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_quota_groups" not in self._stubs: - self._stubs["list_quota_groups"] = self.grpc_channel.unary_unary( + self._stubs["list_quota_groups"] = self._logged_channel.unary_unary( "/google.shopping.merchant.quota.v1beta.QuotaService/ListQuotaGroups", request_serializer=quota.ListQuotaGroupsRequest.serialize, response_deserializer=quota.ListQuotaGroupsResponse.deserialize, @@ -263,7 +349,7 @@ def list_quota_groups( return self._stubs["list_quota_groups"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc_asyncio.py index 7e3d06377006..0e8cd43684fd 100644 --- a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -22,14 +25,93 @@ 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 from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_quota_v1beta.types import quota from .base import DEFAULT_CLIENT_INFO, QuotaServiceTransport from .grpc import QuotaServiceGrpcTransport +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.shopping.merchant.quota.v1beta.QuotaService", + "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.shopping.merchant.quota.v1beta.QuotaService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class QuotaServiceGrpcAsyncIOTransport(QuotaServiceTransport): """gRPC AsyncIO backend transport for QuotaService. @@ -227,10 +309,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 @@ -265,7 +350,7 @@ def list_quota_groups( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_quota_groups" not in self._stubs: - self._stubs["list_quota_groups"] = self.grpc_channel.unary_unary( + self._stubs["list_quota_groups"] = self._logged_channel.unary_unary( "/google.shopping.merchant.quota.v1beta.QuotaService/ListQuotaGroups", request_serializer=quota.ListQuotaGroupsRequest.serialize, response_deserializer=quota.ListQuotaGroupsResponse.deserialize, @@ -288,7 +373,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/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest.py b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest.py index b4b942f6e478..7ed3514e74c5 100644 --- a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest.py +++ b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -37,6 +37,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, @@ -75,8 +83,10 @@ def post_list_quota_groups(self, response): """ def pre_list_quota_groups( - self, request: quota.ListQuotaGroupsRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[quota.ListQuotaGroupsRequest, Sequence[Tuple[str, str]]]: + self, + request: quota.ListQuotaGroupsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[quota.ListQuotaGroupsRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for list_quota_groups Override in a subclass to manipulate the request or metadata @@ -217,7 +227,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]]] = (), ) -> quota.ListQuotaGroupsResponse: r"""Call the list quota groups method over HTTP. @@ -228,8 +238,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: ~.quota.ListQuotaGroupsResponse: @@ -241,6 +253,7 @@ def __call__( http_options = ( _BaseQuotaServiceRestTransport._BaseListQuotaGroups._get_http_options() ) + request, metadata = self._interceptor.pre_list_quota_groups( request, metadata ) @@ -253,6 +266,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.shopping.merchant.quota_v1beta.QuotaServiceClient.ListQuotaGroups", + extra={ + "serviceName": "google.shopping.merchant.quota.v1beta.QuotaService", + "rpcName": "ListQuotaGroups", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = QuotaServiceRestTransport._ListQuotaGroups._get_response( self._host, @@ -273,7 +313,29 @@ def __call__( pb_resp = quota.ListQuotaGroupsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_quota_groups(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = quota.ListQuotaGroupsResponse.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.shopping.merchant.quota_v1beta.QuotaServiceClient.list_quota_groups", + extra={ + "serviceName": "google.shopping.merchant.quota.v1beta.QuotaService", + "rpcName": "ListQuotaGroups", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-quota/samples/generated_samples/snippet_metadata_google.shopping.merchant.quota.v1beta.json b/packages/google-shopping-merchant-quota/samples/generated_samples/snippet_metadata_google.shopping.merchant.quota.v1beta.json index bae6584d26a7..48037ddf7f53 100644 --- a/packages/google-shopping-merchant-quota/samples/generated_samples/snippet_metadata_google.shopping.merchant.quota.v1beta.json +++ b/packages/google-shopping-merchant-quota/samples/generated_samples/snippet_metadata_google.shopping.merchant.quota.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-shopping-merchant-quota", - "version": "0.1.4" + "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.shopping.merchant_quota_v1beta.services.quota_service.pagers.ListQuotaGroupsAsyncPager", @@ -127,7 +127,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_quota_v1beta.services.quota_service.pagers.ListQuotaGroupsPager", diff --git a/packages/google-shopping-merchant-quota/tests/unit/gapic/merchant_quota_v1beta/test_quota_service.py b/packages/google-shopping-merchant-quota/tests/unit/gapic/merchant_quota_v1beta/test_quota_service.py index 6c89da5d8846..134ab619ae82 100644 --- a/packages/google-shopping-merchant-quota/tests/unit/gapic/merchant_quota_v1beta/test_quota_service.py +++ b/packages/google-shopping-merchant-quota/tests/unit/gapic/merchant_quota_v1beta/test_quota_service.py @@ -1691,6 +1691,7 @@ def test_list_quota_groups_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_quota_groups(request) @@ -1744,6 +1745,7 @@ def test_list_quota_groups_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_quota_groups(**mock_args) @@ -2031,6 +2033,7 @@ def test_list_quota_groups_rest_bad_request(request_type=quota.ListQuotaGroupsRe 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_quota_groups(request) @@ -2066,6 +2069,7 @@ def test_list_quota_groups_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_quota_groups(request) # Establish that the response is the type that we expect. @@ -2104,6 +2108,7 @@ def test_list_quota_groups_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 = quota.ListQuotaGroupsResponse.to_json( quota.ListQuotaGroupsResponse() ) diff --git a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports/gapic_version.py b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports/gapic_version.py index 4b834789ba9e..558c8aab67c5 100644 --- a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports/gapic_version.py +++ b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.11" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/gapic_version.py b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/gapic_version.py index 4b834789ba9e..558c8aab67c5 100644 --- a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/gapic_version.py +++ b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.11" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/async_client.py b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/async_client.py index f43a77eca125..722e7e68fbf0 100644 --- a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/async_client.py +++ b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -49,6 +50,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, ReportServiceTransport from .transports.grpc_asyncio import ReportServiceGrpcAsyncIOTransport +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 ReportServiceAsyncClient: """Service for retrieving reports and insights about your @@ -255,6 +265,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.shopping.merchant.reports_v1beta.ReportServiceAsyncClient`.", + extra={ + "serviceName": "google.shopping.merchant.reports.v1beta.ReportService", + "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.shopping.merchant.reports.v1beta.ReportService", + "credentialsType": None, + }, + ) + async def search( self, request: Optional[Union[reports.SearchRequest, dict]] = None, @@ -262,7 +294,7 @@ async def search( 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.SearchAsyncPager: r"""Retrieves a report defined by a search query. The response might contain fewer rows than specified by ``page_size``. Rely on @@ -312,8 +344,10 @@ async def sample_search(): 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.shopping.merchant_reports_v1beta.services.report_service.pagers.SearchAsyncPager: diff --git a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/client.py b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/client.py index 9f4d0d3f14f6..a80610a97821 100644 --- a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/client.py +++ b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.shopping.merchant_reports_v1beta.services.report_service import pagers from google.shopping.merchant_reports_v1beta.types import reports @@ -557,6 +567,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( @@ -622,6 +636,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.shopping.merchant.reports_v1beta.ReportServiceClient`.", + extra={ + "serviceName": "google.shopping.merchant.reports.v1beta.ReportService", + "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.shopping.merchant.reports.v1beta.ReportService", + "credentialsType": None, + }, + ) + def search( self, request: Optional[Union[reports.SearchRequest, dict]] = None, @@ -629,7 +666,7 @@ def search( 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.SearchPager: r"""Retrieves a report defined by a search query. The response might contain fewer rows than specified by ``page_size``. Rely on @@ -679,8 +716,10 @@ def sample_search(): 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.shopping.merchant_reports_v1beta.services.report_service.pagers.SearchPager: diff --git a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/pagers.py b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/pagers.py index 3fef73be964b..53493a567e5d 100644 --- a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/pagers.py +++ b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/pagers.py @@ -67,7 +67,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. @@ -81,8 +81,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 = reports.SearchRequest(request) @@ -141,7 +143,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. @@ -155,8 +157,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 = reports.SearchRequest(request) diff --git a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc.py b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc.py index 0e1635e22b97..dc64e334ca53 100644 --- a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc.py +++ b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -20,12 +23,90 @@ 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.shopping.merchant_reports_v1beta.types import reports from .base import DEFAULT_CLIENT_INFO, ReportServiceTransport +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.shopping.merchant.reports.v1beta.ReportService", + "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.shopping.merchant.reports.v1beta.ReportService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class ReportServiceGrpcTransport(ReportServiceTransport): """gRPC backend transport for ReportService. @@ -181,7 +262,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 @@ -256,7 +342,7 @@ def search(self) -> Callable[[reports.SearchRequest], reports.SearchResponse]: # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "search" not in self._stubs: - self._stubs["search"] = self.grpc_channel.unary_unary( + self._stubs["search"] = self._logged_channel.unary_unary( "/google.shopping.merchant.reports.v1beta.ReportService/Search", request_serializer=reports.SearchRequest.serialize, response_deserializer=reports.SearchResponse.deserialize, @@ -264,7 +350,7 @@ def search(self) -> Callable[[reports.SearchRequest], reports.SearchResponse]: return self._stubs["search"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc_asyncio.py index 881e4604c9c7..90a6d38f3eae 100644 --- a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -22,14 +25,93 @@ 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 from grpc.experimental import aio # type: ignore +import proto # type: ignore from google.shopping.merchant_reports_v1beta.types import reports from .base import DEFAULT_CLIENT_INFO, ReportServiceTransport from .grpc import ReportServiceGrpcTransport +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.shopping.merchant.reports.v1beta.ReportService", + "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.shopping.merchant.reports.v1beta.ReportService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class ReportServiceGrpcAsyncIOTransport(ReportServiceTransport): """gRPC AsyncIO backend transport for ReportService. @@ -228,10 +310,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 @@ -266,7 +351,7 @@ def search( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "search" not in self._stubs: - self._stubs["search"] = self.grpc_channel.unary_unary( + self._stubs["search"] = self._logged_channel.unary_unary( "/google.shopping.merchant.reports.v1beta.ReportService/Search", request_serializer=reports.SearchRequest.serialize, response_deserializer=reports.SearchResponse.deserialize, @@ -289,7 +374,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/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest.py b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest.py index 50a907ac8a5a..8d9fb0e16582 100644 --- a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest.py +++ b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -37,6 +37,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, @@ -75,8 +83,10 @@ def post_search(self, response): """ def pre_search( - self, request: reports.SearchRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[reports.SearchRequest, Sequence[Tuple[str, str]]]: + self, + request: reports.SearchRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[reports.SearchRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for search Override in a subclass to manipulate the request or metadata @@ -215,7 +225,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]]] = (), ) -> reports.SearchResponse: r"""Call the search method over HTTP. @@ -225,8 +235,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: ~.reports.SearchResponse: @@ -238,6 +250,7 @@ def __call__( http_options = ( _BaseReportServiceRestTransport._BaseSearch._get_http_options() ) + request, metadata = self._interceptor.pre_search(request, metadata) transcoded_request = ( _BaseReportServiceRestTransport._BaseSearch._get_transcoded_request( @@ -256,6 +269,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.shopping.merchant.reports_v1beta.ReportServiceClient.Search", + extra={ + "serviceName": "google.shopping.merchant.reports.v1beta.ReportService", + "rpcName": "Search", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = ReportServiceRestTransport._Search._get_response( self._host, @@ -277,7 +317,29 @@ def __call__( pb_resp = reports.SearchResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_search(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = reports.SearchResponse.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.shopping.merchant.reports_v1beta.ReportServiceClient.search", + extra={ + "serviceName": "google.shopping.merchant.reports.v1beta.ReportService", + "rpcName": "Search", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/google-shopping-merchant-reports/samples/generated_samples/snippet_metadata_google.shopping.merchant.reports.v1beta.json b/packages/google-shopping-merchant-reports/samples/generated_samples/snippet_metadata_google.shopping.merchant.reports.v1beta.json index 35302936be5d..145fa5b7eb46 100644 --- a/packages/google-shopping-merchant-reports/samples/generated_samples/snippet_metadata_google.shopping.merchant.reports.v1beta.json +++ b/packages/google-shopping-merchant-reports/samples/generated_samples/snippet_metadata_google.shopping.merchant.reports.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-shopping-merchant-reports", - "version": "0.1.11" + "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.shopping.merchant_reports_v1beta.services.report_service.pagers.SearchAsyncPager", @@ -127,7 +127,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "google.shopping.merchant_reports_v1beta.services.report_service.pagers.SearchPager", diff --git a/packages/google-shopping-merchant-reports/tests/unit/gapic/merchant_reports_v1beta/test_report_service.py b/packages/google-shopping-merchant-reports/tests/unit/gapic/merchant_reports_v1beta/test_report_service.py index 4fd0b9e51eef..64cffda0a359 100644 --- a/packages/google-shopping-merchant-reports/tests/unit/gapic/merchant_reports_v1beta/test_report_service.py +++ b/packages/google-shopping-merchant-reports/tests/unit/gapic/merchant_reports_v1beta/test_report_service.py @@ -1678,6 +1678,7 @@ def test_search_rest_required_fields(request_type=reports.SearchRequest): 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.search(request) @@ -1731,6 +1732,7 @@ def test_search_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.search(**mock_args) @@ -2015,6 +2017,7 @@ def test_search_rest_bad_request(request_type=reports.SearchRequest): 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.search(request) @@ -2050,6 +2053,7 @@ def test_search_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.search(request) # Establish that the response is the type that we expect. @@ -2088,6 +2092,7 @@ def test_search_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 = reports.SearchResponse.to_json(reports.SearchResponse()) req.return_value.content = return_value diff --git a/packages/grafeas/grafeas/grafeas/gapic_version.py b/packages/grafeas/grafeas/grafeas/gapic_version.py index 49ddc22ee702..558c8aab67c5 100644 --- a/packages/grafeas/grafeas/grafeas/gapic_version.py +++ b/packages/grafeas/grafeas/grafeas/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.12.1" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/grafeas/grafeas/grafeas_v1/gapic_version.py b/packages/grafeas/grafeas/grafeas_v1/gapic_version.py index 49ddc22ee702..558c8aab67c5 100644 --- a/packages/grafeas/grafeas/grafeas_v1/gapic_version.py +++ b/packages/grafeas/grafeas/grafeas_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.12.1" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/async_client.py b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/async_client.py index f18d20debe1d..2c520c5a0b0d 100644 --- a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/async_client.py +++ b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/async_client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import re from typing import ( Callable, @@ -67,6 +68,15 @@ from .transports.base import DEFAULT_CLIENT_INFO, GrafeasTransport from .transports.grpc_asyncio import GrafeasGrpcAsyncIOTransport +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 GrafeasAsyncClient: """`Grafeas `__ API. @@ -165,6 +175,28 @@ def __init__( credentials=credentials, ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `grafeas_v1.GrafeasAsyncClient`.", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "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": "grafeas.v1.Grafeas", + "credentialsType": None, + }, + ) + async def get_occurrence( self, request: Optional[Union[grafeas.GetOccurrenceRequest, dict]] = None, @@ -172,7 +204,7 @@ async def get_occurrence( 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]]] = (), ) -> grafeas.Occurrence: r"""Gets the specified occurrence. @@ -215,8 +247,10 @@ async def sample_get_occurrence(): 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: grafeas.grafeas_v1.types.Occurrence: @@ -275,7 +309,7 @@ async def list_occurrences( filter: 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.ListOccurrencesAsyncPager: r"""Lists occurrences for the specified project. @@ -324,8 +358,10 @@ async def sample_list_occurrences(): 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: grafeas.grafeas_v1.services.grafeas.pagers.ListOccurrencesAsyncPager: @@ -399,7 +435,7 @@ async def delete_occurrence( 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 the specified occurrence. For example, use this method to delete an occurrence when the occurrence @@ -441,8 +477,10 @@ async def sample_delete_occurrence(): 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 @@ -492,7 +530,7 @@ async def create_occurrence( occurrence: Optional[grafeas.Occurrence] = 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]]] = (), ) -> grafeas.Occurrence: r"""Creates a new occurrence. @@ -541,8 +579,10 @@ async def sample_create_occurrence(): 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: grafeas.grafeas_v1.types.Occurrence: @@ -603,7 +643,7 @@ async def batch_create_occurrences( occurrences: Optional[MutableSequence[grafeas.Occurrence]] = 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]]] = (), ) -> grafeas.BatchCreateOccurrencesResponse: r"""Creates new occurrences in batch. @@ -655,8 +695,10 @@ async def sample_batch_create_occurrences(): 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: grafeas.grafeas_v1.types.BatchCreateOccurrencesResponse: @@ -718,7 +760,7 @@ async def update_occurrence( 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]]] = (), ) -> grafeas.Occurrence: r"""Updates the specified occurrence. @@ -771,8 +813,10 @@ async def sample_update_occurrence(): 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: grafeas.grafeas_v1.types.Occurrence: @@ -834,7 +878,7 @@ async def get_occurrence_note( 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]]] = (), ) -> grafeas.Note: r"""Gets the note attached to the specified occurrence. Consumer projects can use this method to get a note that @@ -880,8 +924,10 @@ async def sample_get_occurrence_note(): 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: grafeas.grafeas_v1.types.Note: @@ -939,7 +985,7 @@ async def get_note( 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]]] = (), ) -> grafeas.Note: r"""Gets the specified note. @@ -982,8 +1028,10 @@ async def sample_get_note(): 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: grafeas.grafeas_v1.types.Note: @@ -1040,7 +1088,7 @@ async def list_notes( filter: 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.ListNotesAsyncPager: r"""Lists notes for the specified project. @@ -1089,8 +1137,10 @@ async def sample_list_notes(): 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: grafeas.grafeas_v1.services.grafeas.pagers.ListNotesAsyncPager: @@ -1164,7 +1214,7 @@ async def delete_note( 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 the specified note. @@ -1204,8 +1254,10 @@ async def sample_delete_note(): 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 @@ -1256,7 +1308,7 @@ async def create_note( note: Optional[grafeas.Note] = 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]]] = (), ) -> grafeas.Note: r"""Creates a new note. @@ -1311,8 +1363,10 @@ async def sample_create_note(): 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: grafeas.grafeas_v1.types.Note: @@ -1375,7 +1429,7 @@ async def batch_create_notes( notes: Optional[MutableMapping[str, grafeas.Note]] = 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]]] = (), ) -> grafeas.BatchCreateNotesResponse: r"""Creates new notes in batch. @@ -1426,8 +1480,10 @@ async def sample_batch_create_notes(): 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: grafeas.grafeas_v1.types.BatchCreateNotesResponse: @@ -1488,7 +1544,7 @@ async def update_note( 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]]] = (), ) -> grafeas.Note: r"""Updates the specified note. @@ -1541,8 +1597,10 @@ async def sample_update_note(): 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: grafeas.grafeas_v1.types.Note: @@ -1605,7 +1663,7 @@ async def list_note_occurrences( filter: 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.ListNoteOccurrencesAsyncPager: r"""Lists occurrences referencing the specified note. Provider projects can use this method to get all @@ -1658,8 +1716,10 @@ async def sample_list_note_occurrences(): 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: grafeas.grafeas_v1.services.grafeas.pagers.ListNoteOccurrencesAsyncPager: diff --git a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/client.py b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/client.py index 1e3d2e5b01fc..51567402e6b4 100644 --- a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/client.py +++ b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/client.py @@ -14,6 +14,7 @@ # limitations under the License. # from collections import OrderedDict +import logging as std_logging import os import re from typing import ( @@ -48,6 +49,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.protobuf import field_mask_pb2 # type: ignore from google.protobuf import timestamp_pb2 # type: ignore @@ -349,7 +359,7 @@ def get_occurrence( 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]]] = (), ) -> grafeas.Occurrence: r"""Gets the specified occurrence. @@ -392,8 +402,10 @@ def sample_get_occurrence(): 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: grafeas.grafeas_v1.types.Occurrence: @@ -449,7 +461,7 @@ def list_occurrences( filter: 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.ListOccurrencesPager: r"""Lists occurrences for the specified project. @@ -498,8 +510,10 @@ def sample_list_occurrences(): 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: grafeas.grafeas_v1.services.grafeas.pagers.ListOccurrencesPager: @@ -570,7 +584,7 @@ def delete_occurrence( 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 the specified occurrence. For example, use this method to delete an occurrence when the occurrence @@ -612,8 +626,10 @@ def sample_delete_occurrence(): 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 @@ -660,7 +676,7 @@ def create_occurrence( occurrence: Optional[grafeas.Occurrence] = 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]]] = (), ) -> grafeas.Occurrence: r"""Creates a new occurrence. @@ -709,8 +725,10 @@ def sample_create_occurrence(): 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: grafeas.grafeas_v1.types.Occurrence: @@ -768,7 +786,7 @@ def batch_create_occurrences( occurrences: Optional[MutableSequence[grafeas.Occurrence]] = 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]]] = (), ) -> grafeas.BatchCreateOccurrencesResponse: r"""Creates new occurrences in batch. @@ -820,8 +838,10 @@ def sample_batch_create_occurrences(): 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: grafeas.grafeas_v1.types.BatchCreateOccurrencesResponse: @@ -880,7 +900,7 @@ def update_occurrence( 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]]] = (), ) -> grafeas.Occurrence: r"""Updates the specified occurrence. @@ -933,8 +953,10 @@ def sample_update_occurrence(): 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: grafeas.grafeas_v1.types.Occurrence: @@ -993,7 +1015,7 @@ def get_occurrence_note( 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]]] = (), ) -> grafeas.Note: r"""Gets the note attached to the specified occurrence. Consumer projects can use this method to get a note that @@ -1039,8 +1061,10 @@ def sample_get_occurrence_note(): 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: grafeas.grafeas_v1.types.Note: @@ -1095,7 +1119,7 @@ def get_note( 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]]] = (), ) -> grafeas.Note: r"""Gets the specified note. @@ -1138,8 +1162,10 @@ def sample_get_note(): 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: grafeas.grafeas_v1.types.Note: @@ -1195,7 +1221,7 @@ def list_notes( filter: 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.ListNotesPager: r"""Lists notes for the specified project. @@ -1244,8 +1270,10 @@ def sample_list_notes(): 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: grafeas.grafeas_v1.services.grafeas.pagers.ListNotesPager: @@ -1316,7 +1344,7 @@ def delete_note( 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 the specified note. @@ -1356,8 +1384,10 @@ def sample_delete_note(): 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 @@ -1405,7 +1435,7 @@ def create_note( note: Optional[grafeas.Note] = 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]]] = (), ) -> grafeas.Note: r"""Creates a new note. @@ -1460,8 +1490,10 @@ def sample_create_note(): 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: grafeas.grafeas_v1.types.Note: @@ -1521,7 +1553,7 @@ def batch_create_notes( notes: Optional[MutableMapping[str, grafeas.Note]] = 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]]] = (), ) -> grafeas.BatchCreateNotesResponse: r"""Creates new notes in batch. @@ -1572,8 +1604,10 @@ def sample_batch_create_notes(): 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: grafeas.grafeas_v1.types.BatchCreateNotesResponse: @@ -1630,7 +1664,7 @@ def update_note( 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]]] = (), ) -> grafeas.Note: r"""Updates the specified note. @@ -1683,8 +1717,10 @@ def sample_update_note(): 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: grafeas.grafeas_v1.types.Note: @@ -1744,7 +1780,7 @@ def list_note_occurrences( filter: 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.ListNoteOccurrencesPager: r"""Lists occurrences referencing the specified note. Provider projects can use this method to get all @@ -1797,8 +1833,10 @@ def sample_list_note_occurrences(): 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: grafeas.grafeas_v1.services.grafeas.pagers.ListNoteOccurrencesPager: diff --git a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/pagers.py b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/pagers.py index 04365d168fdc..35de58effe78 100644 --- a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/pagers.py +++ b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/pagers.py @@ -67,7 +67,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. @@ -81,8 +81,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 = grafeas.ListOccurrencesRequest(request) @@ -141,7 +143,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. @@ -155,8 +157,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 = grafeas.ListOccurrencesRequest(request) @@ -219,7 +223,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. @@ -233,8 +237,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 = grafeas.ListNotesRequest(request) @@ -293,7 +299,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. @@ -307,8 +313,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 = grafeas.ListNotesRequest(request) @@ -371,7 +379,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. @@ -385,8 +393,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 = grafeas.ListNoteOccurrencesRequest(request) @@ -445,7 +455,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. @@ -459,8 +469,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 = grafeas.ListNoteOccurrencesRequest(request) diff --git a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/grpc.py b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/grpc.py index 7ebadac51ede..079acc044c88 100644 --- a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/grpc.py +++ b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/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 from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -21,12 +24,90 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore +import proto # type: ignore from grafeas.grafeas_v1.types import grafeas from .base import DEFAULT_CLIENT_INFO, GrafeasTransport +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": "grafeas.v1.Grafeas", + "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": "grafeas.v1.Grafeas", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class GrafeasGrpcTransport(GrafeasTransport): """gRPC backend transport for Grafeas. @@ -195,7 +276,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 @@ -269,7 +355,7 @@ def get_occurrence( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_occurrence" not in self._stubs: - self._stubs["get_occurrence"] = self.grpc_channel.unary_unary( + self._stubs["get_occurrence"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/GetOccurrence", request_serializer=grafeas.GetOccurrenceRequest.serialize, response_deserializer=grafeas.Occurrence.deserialize, @@ -295,7 +381,7 @@ def list_occurrences( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_occurrences" not in self._stubs: - self._stubs["list_occurrences"] = self.grpc_channel.unary_unary( + self._stubs["list_occurrences"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/ListOccurrences", request_serializer=grafeas.ListOccurrencesRequest.serialize, response_deserializer=grafeas.ListOccurrencesResponse.deserialize, @@ -323,7 +409,7 @@ def delete_occurrence( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_occurrence" not in self._stubs: - self._stubs["delete_occurrence"] = self.grpc_channel.unary_unary( + self._stubs["delete_occurrence"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/DeleteOccurrence", request_serializer=grafeas.DeleteOccurrenceRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -349,7 +435,7 @@ def create_occurrence( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_occurrence" not in self._stubs: - self._stubs["create_occurrence"] = self.grpc_channel.unary_unary( + self._stubs["create_occurrence"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/CreateOccurrence", request_serializer=grafeas.CreateOccurrenceRequest.serialize, response_deserializer=grafeas.Occurrence.deserialize, @@ -377,7 +463,7 @@ def batch_create_occurrences( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "batch_create_occurrences" not in self._stubs: - self._stubs["batch_create_occurrences"] = self.grpc_channel.unary_unary( + self._stubs["batch_create_occurrences"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/BatchCreateOccurrences", request_serializer=grafeas.BatchCreateOccurrencesRequest.serialize, response_deserializer=grafeas.BatchCreateOccurrencesResponse.deserialize, @@ -403,7 +489,7 @@ def update_occurrence( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_occurrence" not in self._stubs: - self._stubs["update_occurrence"] = self.grpc_channel.unary_unary( + self._stubs["update_occurrence"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/UpdateOccurrence", request_serializer=grafeas.UpdateOccurrenceRequest.serialize, response_deserializer=grafeas.Occurrence.deserialize, @@ -431,7 +517,7 @@ def get_occurrence_note( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_occurrence_note" not in self._stubs: - self._stubs["get_occurrence_note"] = self.grpc_channel.unary_unary( + self._stubs["get_occurrence_note"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/GetOccurrenceNote", request_serializer=grafeas.GetOccurrenceNoteRequest.serialize, response_deserializer=grafeas.Note.deserialize, @@ -455,7 +541,7 @@ def get_note(self) -> Callable[[grafeas.GetNoteRequest], grafeas.Note]: # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_note" not in self._stubs: - self._stubs["get_note"] = self.grpc_channel.unary_unary( + self._stubs["get_note"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/GetNote", request_serializer=grafeas.GetNoteRequest.serialize, response_deserializer=grafeas.Note.deserialize, @@ -481,7 +567,7 @@ def list_notes( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_notes" not in self._stubs: - self._stubs["list_notes"] = self.grpc_channel.unary_unary( + self._stubs["list_notes"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/ListNotes", request_serializer=grafeas.ListNotesRequest.serialize, response_deserializer=grafeas.ListNotesResponse.deserialize, @@ -505,7 +591,7 @@ def delete_note(self) -> Callable[[grafeas.DeleteNoteRequest], empty_pb2.Empty]: # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_note" not in self._stubs: - self._stubs["delete_note"] = self.grpc_channel.unary_unary( + self._stubs["delete_note"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/DeleteNote", request_serializer=grafeas.DeleteNoteRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -529,7 +615,7 @@ def create_note(self) -> Callable[[grafeas.CreateNoteRequest], grafeas.Note]: # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_note" not in self._stubs: - self._stubs["create_note"] = self.grpc_channel.unary_unary( + self._stubs["create_note"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/CreateNote", request_serializer=grafeas.CreateNoteRequest.serialize, response_deserializer=grafeas.Note.deserialize, @@ -555,7 +641,7 @@ def batch_create_notes( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "batch_create_notes" not in self._stubs: - self._stubs["batch_create_notes"] = self.grpc_channel.unary_unary( + self._stubs["batch_create_notes"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/BatchCreateNotes", request_serializer=grafeas.BatchCreateNotesRequest.serialize, response_deserializer=grafeas.BatchCreateNotesResponse.deserialize, @@ -579,7 +665,7 @@ def update_note(self) -> Callable[[grafeas.UpdateNoteRequest], grafeas.Note]: # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_note" not in self._stubs: - self._stubs["update_note"] = self.grpc_channel.unary_unary( + self._stubs["update_note"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/UpdateNote", request_serializer=grafeas.UpdateNoteRequest.serialize, response_deserializer=grafeas.Note.deserialize, @@ -610,7 +696,7 @@ def list_note_occurrences( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_note_occurrences" not in self._stubs: - self._stubs["list_note_occurrences"] = self.grpc_channel.unary_unary( + self._stubs["list_note_occurrences"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/ListNoteOccurrences", request_serializer=grafeas.ListNoteOccurrencesRequest.serialize, response_deserializer=grafeas.ListNoteOccurrencesResponse.deserialize, @@ -618,7 +704,7 @@ def list_note_occurrences( return self._stubs["list_note_occurrences"] def close(self): - self.grpc_channel.close() + self._logged_channel.close() @property def kind(self) -> str: diff --git a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/grpc_asyncio.py b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/grpc_asyncio.py index 4e5d15d67078..5e80e76ad90f 100644 --- a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/grpc_asyncio.py +++ b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/grpc_asyncio.py @@ -14,6 +14,9 @@ # limitations under the License. # import inspect +import json +import logging as std_logging +import pickle from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -23,14 +26,93 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message import grpc # type: ignore from grpc.experimental import aio # type: ignore +import proto # type: ignore from grafeas.grafeas_v1.types import grafeas from .base import DEFAULT_CLIENT_INFO, GrafeasTransport from .grpc import GrafeasGrpcTransport +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": "grafeas.v1.Grafeas", + "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": "grafeas.v1.Grafeas", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + class GrafeasGrpcAsyncIOTransport(GrafeasTransport): """gRPC AsyncIO backend transport for Grafeas. @@ -242,10 +324,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 @@ -277,7 +362,7 @@ def get_occurrence( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_occurrence" not in self._stubs: - self._stubs["get_occurrence"] = self.grpc_channel.unary_unary( + self._stubs["get_occurrence"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/GetOccurrence", request_serializer=grafeas.GetOccurrenceRequest.serialize, response_deserializer=grafeas.Occurrence.deserialize, @@ -305,7 +390,7 @@ def list_occurrences( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_occurrences" not in self._stubs: - self._stubs["list_occurrences"] = self.grpc_channel.unary_unary( + self._stubs["list_occurrences"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/ListOccurrences", request_serializer=grafeas.ListOccurrencesRequest.serialize, response_deserializer=grafeas.ListOccurrencesResponse.deserialize, @@ -333,7 +418,7 @@ def delete_occurrence( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_occurrence" not in self._stubs: - self._stubs["delete_occurrence"] = self.grpc_channel.unary_unary( + self._stubs["delete_occurrence"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/DeleteOccurrence", request_serializer=grafeas.DeleteOccurrenceRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -359,7 +444,7 @@ def create_occurrence( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_occurrence" not in self._stubs: - self._stubs["create_occurrence"] = self.grpc_channel.unary_unary( + self._stubs["create_occurrence"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/CreateOccurrence", request_serializer=grafeas.CreateOccurrenceRequest.serialize, response_deserializer=grafeas.Occurrence.deserialize, @@ -388,7 +473,7 @@ def batch_create_occurrences( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "batch_create_occurrences" not in self._stubs: - self._stubs["batch_create_occurrences"] = self.grpc_channel.unary_unary( + self._stubs["batch_create_occurrences"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/BatchCreateOccurrences", request_serializer=grafeas.BatchCreateOccurrencesRequest.serialize, response_deserializer=grafeas.BatchCreateOccurrencesResponse.deserialize, @@ -414,7 +499,7 @@ def update_occurrence( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_occurrence" not in self._stubs: - self._stubs["update_occurrence"] = self.grpc_channel.unary_unary( + self._stubs["update_occurrence"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/UpdateOccurrence", request_serializer=grafeas.UpdateOccurrenceRequest.serialize, response_deserializer=grafeas.Occurrence.deserialize, @@ -442,7 +527,7 @@ def get_occurrence_note( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_occurrence_note" not in self._stubs: - self._stubs["get_occurrence_note"] = self.grpc_channel.unary_unary( + self._stubs["get_occurrence_note"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/GetOccurrenceNote", request_serializer=grafeas.GetOccurrenceNoteRequest.serialize, response_deserializer=grafeas.Note.deserialize, @@ -466,7 +551,7 @@ def get_note(self) -> Callable[[grafeas.GetNoteRequest], Awaitable[grafeas.Note] # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "get_note" not in self._stubs: - self._stubs["get_note"] = self.grpc_channel.unary_unary( + self._stubs["get_note"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/GetNote", request_serializer=grafeas.GetNoteRequest.serialize, response_deserializer=grafeas.Note.deserialize, @@ -492,7 +577,7 @@ def list_notes( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_notes" not in self._stubs: - self._stubs["list_notes"] = self.grpc_channel.unary_unary( + self._stubs["list_notes"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/ListNotes", request_serializer=grafeas.ListNotesRequest.serialize, response_deserializer=grafeas.ListNotesResponse.deserialize, @@ -518,7 +603,7 @@ def delete_note( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "delete_note" not in self._stubs: - self._stubs["delete_note"] = self.grpc_channel.unary_unary( + self._stubs["delete_note"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/DeleteNote", request_serializer=grafeas.DeleteNoteRequest.serialize, response_deserializer=empty_pb2.Empty.FromString, @@ -544,7 +629,7 @@ def create_note( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "create_note" not in self._stubs: - self._stubs["create_note"] = self.grpc_channel.unary_unary( + self._stubs["create_note"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/CreateNote", request_serializer=grafeas.CreateNoteRequest.serialize, response_deserializer=grafeas.Note.deserialize, @@ -572,7 +657,7 @@ def batch_create_notes( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "batch_create_notes" not in self._stubs: - self._stubs["batch_create_notes"] = self.grpc_channel.unary_unary( + self._stubs["batch_create_notes"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/BatchCreateNotes", request_serializer=grafeas.BatchCreateNotesRequest.serialize, response_deserializer=grafeas.BatchCreateNotesResponse.deserialize, @@ -598,7 +683,7 @@ def update_note( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "update_note" not in self._stubs: - self._stubs["update_note"] = self.grpc_channel.unary_unary( + self._stubs["update_note"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/UpdateNote", request_serializer=grafeas.UpdateNoteRequest.serialize, response_deserializer=grafeas.Note.deserialize, @@ -630,7 +715,7 @@ def list_note_occurrences( # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. if "list_note_occurrences" not in self._stubs: - self._stubs["list_note_occurrences"] = self.grpc_channel.unary_unary( + self._stubs["list_note_occurrences"] = self._logged_channel.unary_unary( "/grafeas.v1.Grafeas/ListNoteOccurrences", request_serializer=grafeas.ListNoteOccurrencesRequest.serialize, response_deserializer=grafeas.ListNoteOccurrencesResponse.deserialize, @@ -798,7 +883,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/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/rest.py b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/rest.py index 4403a5301af3..96821ab0a7ee 100644 --- a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/rest.py +++ b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/rest.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import dataclasses import json # type: ignore +import logging from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings @@ -38,6 +38,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, @@ -174,8 +182,10 @@ def post_update_occurrence(self, response): def pre_batch_create_notes( self, request: grafeas.BatchCreateNotesRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[grafeas.BatchCreateNotesRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + grafeas.BatchCreateNotesRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for batch_create_notes Override in a subclass to manipulate the request or metadata @@ -197,8 +207,10 @@ def post_batch_create_notes( def pre_batch_create_occurrences( self, request: grafeas.BatchCreateOccurrencesRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[grafeas.BatchCreateOccurrencesRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + grafeas.BatchCreateOccurrencesRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for batch_create_occurrences Override in a subclass to manipulate the request or metadata @@ -218,8 +230,10 @@ def post_batch_create_occurrences( return response def pre_create_note( - self, request: grafeas.CreateNoteRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[grafeas.CreateNoteRequest, Sequence[Tuple[str, str]]]: + self, + request: grafeas.CreateNoteRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[grafeas.CreateNoteRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for create_note Override in a subclass to manipulate the request or metadata @@ -239,8 +253,10 @@ def post_create_note(self, response: grafeas.Note) -> grafeas.Note: def pre_create_occurrence( self, request: grafeas.CreateOccurrenceRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[grafeas.CreateOccurrenceRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + grafeas.CreateOccurrenceRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for create_occurrence Override in a subclass to manipulate the request or metadata @@ -260,8 +276,10 @@ def post_create_occurrence( return response def pre_delete_note( - self, request: grafeas.DeleteNoteRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[grafeas.DeleteNoteRequest, Sequence[Tuple[str, str]]]: + self, + request: grafeas.DeleteNoteRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[grafeas.DeleteNoteRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for delete_note Override in a subclass to manipulate the request or metadata @@ -272,8 +290,10 @@ def pre_delete_note( def pre_delete_occurrence( self, request: grafeas.DeleteOccurrenceRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[grafeas.DeleteOccurrenceRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + grafeas.DeleteOccurrenceRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for delete_occurrence Override in a subclass to manipulate the request or metadata @@ -282,8 +302,10 @@ def pre_delete_occurrence( return request, metadata def pre_get_note( - self, request: grafeas.GetNoteRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[grafeas.GetNoteRequest, Sequence[Tuple[str, str]]]: + self, + request: grafeas.GetNoteRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[grafeas.GetNoteRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for get_note Override in a subclass to manipulate the request or metadata @@ -301,8 +323,10 @@ def post_get_note(self, response: grafeas.Note) -> grafeas.Note: return response def pre_get_occurrence( - self, request: grafeas.GetOccurrenceRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[grafeas.GetOccurrenceRequest, Sequence[Tuple[str, str]]]: + self, + request: grafeas.GetOccurrenceRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[grafeas.GetOccurrenceRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for get_occurrence Override in a subclass to manipulate the request or metadata @@ -322,8 +346,10 @@ def post_get_occurrence(self, response: grafeas.Occurrence) -> grafeas.Occurrenc def pre_get_occurrence_note( self, request: grafeas.GetOccurrenceNoteRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[grafeas.GetOccurrenceNoteRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + grafeas.GetOccurrenceNoteRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for get_occurrence_note Override in a subclass to manipulate the request or metadata @@ -343,8 +369,10 @@ def post_get_occurrence_note(self, response: grafeas.Note) -> grafeas.Note: def pre_list_note_occurrences( self, request: grafeas.ListNoteOccurrencesRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[grafeas.ListNoteOccurrencesRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + grafeas.ListNoteOccurrencesRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for list_note_occurrences Override in a subclass to manipulate the request or metadata @@ -364,8 +392,10 @@ def post_list_note_occurrences( return response def pre_list_notes( - self, request: grafeas.ListNotesRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[grafeas.ListNotesRequest, Sequence[Tuple[str, str]]]: + self, + request: grafeas.ListNotesRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[grafeas.ListNotesRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for list_notes Override in a subclass to manipulate the request or metadata @@ -387,8 +417,8 @@ def post_list_notes( def pre_list_occurrences( self, request: grafeas.ListOccurrencesRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[grafeas.ListOccurrencesRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[grafeas.ListOccurrencesRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for list_occurrences Override in a subclass to manipulate the request or metadata @@ -408,8 +438,10 @@ def post_list_occurrences( return response def pre_update_note( - self, request: grafeas.UpdateNoteRequest, metadata: Sequence[Tuple[str, str]] - ) -> Tuple[grafeas.UpdateNoteRequest, Sequence[Tuple[str, str]]]: + self, + request: grafeas.UpdateNoteRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[grafeas.UpdateNoteRequest, Sequence[Tuple[str, Union[str, bytes]]]]: """Pre-rpc interceptor for update_note Override in a subclass to manipulate the request or metadata @@ -429,8 +461,10 @@ def post_update_note(self, response: grafeas.Note) -> grafeas.Note: def pre_update_occurrence( self, request: grafeas.UpdateOccurrenceRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[grafeas.UpdateOccurrenceRequest, Sequence[Tuple[str, str]]]: + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + grafeas.UpdateOccurrenceRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: """Pre-rpc interceptor for update_occurrence Override in a subclass to manipulate the request or metadata @@ -586,7 +620,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]]] = (), ) -> grafeas.BatchCreateNotesResponse: r"""Call the batch create notes method over HTTP. @@ -596,8 +630,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: ~.grafeas.BatchCreateNotesResponse: @@ -607,6 +643,7 @@ def __call__( http_options = ( _BaseGrafeasRestTransport._BaseBatchCreateNotes._get_http_options() ) + request, metadata = self._interceptor.pre_batch_create_notes( request, metadata ) @@ -629,6 +666,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 grafeas_v1.GrafeasClient.BatchCreateNotes", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "BatchCreateNotes", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = GrafeasRestTransport._BatchCreateNotes._get_response( self._host, @@ -650,7 +714,31 @@ def __call__( pb_resp = grafeas.BatchCreateNotesResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_batch_create_notes(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = grafeas.BatchCreateNotesResponse.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 grafeas_v1.GrafeasClient.batch_create_notes", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "BatchCreateNotes", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _BatchCreateOccurrences( @@ -688,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]]] = (), ) -> grafeas.BatchCreateOccurrencesResponse: r"""Call the batch create occurrences method over HTTP. @@ -699,8 +787,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: ~.grafeas.BatchCreateOccurrencesResponse: @@ -712,6 +802,7 @@ def __call__( http_options = ( _BaseGrafeasRestTransport._BaseBatchCreateOccurrences._get_http_options() ) + request, metadata = self._interceptor.pre_batch_create_occurrences( request, metadata ) @@ -728,6 +819,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 grafeas_v1.GrafeasClient.BatchCreateOccurrences", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "BatchCreateOccurrences", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = GrafeasRestTransport._BatchCreateOccurrences._get_response( self._host, @@ -749,7 +867,31 @@ def __call__( pb_resp = grafeas.BatchCreateOccurrencesResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_batch_create_occurrences(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = grafeas.BatchCreateOccurrencesResponse.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 grafeas_v1.GrafeasClient.batch_create_occurrences", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "BatchCreateOccurrences", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _CreateNote(_BaseGrafeasRestTransport._BaseCreateNote, GrafeasRestStub): @@ -785,7 +927,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]]] = (), ) -> grafeas.Note: r"""Call the create note method over HTTP. @@ -795,8 +937,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: ~.grafeas.Note: @@ -806,6 +950,7 @@ def __call__( """ http_options = _BaseGrafeasRestTransport._BaseCreateNote._get_http_options() + request, metadata = self._interceptor.pre_create_note(request, metadata) transcoded_request = ( _BaseGrafeasRestTransport._BaseCreateNote._get_transcoded_request( @@ -824,6 +969,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 grafeas_v1.GrafeasClient.CreateNote", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "CreateNote", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = GrafeasRestTransport._CreateNote._get_response( self._host, @@ -845,7 +1017,29 @@ def __call__( pb_resp = grafeas.Note.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_note(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = grafeas.Note.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 grafeas_v1.GrafeasClient.create_note", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "CreateNote", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _CreateOccurrence( @@ -883,7 +1077,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]]] = (), ) -> grafeas.Occurrence: r"""Call the create occurrence method over HTTP. @@ -893,8 +1087,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: ~.grafeas.Occurrence: @@ -906,6 +1102,7 @@ def __call__( http_options = ( _BaseGrafeasRestTransport._BaseCreateOccurrence._get_http_options() ) + request, metadata = self._interceptor.pre_create_occurrence( request, metadata ) @@ -928,6 +1125,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 grafeas_v1.GrafeasClient.CreateOccurrence", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "CreateOccurrence", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = GrafeasRestTransport._CreateOccurrence._get_response( self._host, @@ -949,7 +1173,29 @@ def __call__( pb_resp = grafeas.Occurrence.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_occurrence(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = grafeas.Occurrence.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 grafeas_v1.GrafeasClient.create_occurrence", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "CreateOccurrence", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _DeleteNote(_BaseGrafeasRestTransport._BaseDeleteNote, GrafeasRestStub): @@ -984,7 +1230,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 note method over HTTP. @@ -994,11 +1240,14 @@ 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 = _BaseGrafeasRestTransport._BaseDeleteNote._get_http_options() + request, metadata = self._interceptor.pre_delete_note(request, metadata) transcoded_request = ( _BaseGrafeasRestTransport._BaseDeleteNote._get_transcoded_request( @@ -1013,6 +1262,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 grafeas_v1.GrafeasClient.DeleteNote", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "DeleteNote", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = GrafeasRestTransport._DeleteNote._get_response( self._host, @@ -1062,7 +1338,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 occurrence method over HTTP. @@ -1072,13 +1348,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 = ( _BaseGrafeasRestTransport._BaseDeleteOccurrence._get_http_options() ) + request, metadata = self._interceptor.pre_delete_occurrence( request, metadata ) @@ -1095,6 +1374,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 grafeas_v1.GrafeasClient.DeleteOccurrence", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "DeleteOccurrence", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = GrafeasRestTransport._DeleteOccurrence._get_response( self._host, @@ -1142,7 +1448,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]]] = (), ) -> grafeas.Note: r"""Call the get note method over HTTP. @@ -1152,8 +1458,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: ~.grafeas.Note: @@ -1163,6 +1471,7 @@ def __call__( """ http_options = _BaseGrafeasRestTransport._BaseGetNote._get_http_options() + request, metadata = self._interceptor.pre_get_note(request, metadata) transcoded_request = ( _BaseGrafeasRestTransport._BaseGetNote._get_transcoded_request( @@ -1177,6 +1486,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 grafeas_v1.GrafeasClient.GetNote", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "GetNote", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = GrafeasRestTransport._GetNote._get_response( self._host, @@ -1197,7 +1533,29 @@ def __call__( pb_resp = grafeas.Note.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_note(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = grafeas.Note.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 grafeas_v1.GrafeasClient.get_note", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "GetNote", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _GetOccurrence(_BaseGrafeasRestTransport._BaseGetOccurrence, GrafeasRestStub): @@ -1232,7 +1590,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]]] = (), ) -> grafeas.Occurrence: r"""Call the get occurrence method over HTTP. @@ -1242,8 +1600,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: ~.grafeas.Occurrence: @@ -1255,6 +1615,7 @@ def __call__( http_options = ( _BaseGrafeasRestTransport._BaseGetOccurrence._get_http_options() ) + request, metadata = self._interceptor.pre_get_occurrence(request, metadata) transcoded_request = ( _BaseGrafeasRestTransport._BaseGetOccurrence._get_transcoded_request( @@ -1269,6 +1630,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 grafeas_v1.GrafeasClient.GetOccurrence", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "GetOccurrence", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = GrafeasRestTransport._GetOccurrence._get_response( self._host, @@ -1289,7 +1677,29 @@ def __call__( pb_resp = grafeas.Occurrence.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_occurrence(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = grafeas.Occurrence.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 grafeas_v1.GrafeasClient.get_occurrence", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "GetOccurrence", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _GetOccurrenceNote( @@ -1326,7 +1736,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]]] = (), ) -> grafeas.Note: r"""Call the get occurrence note method over HTTP. @@ -1337,8 +1747,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: ~.grafeas.Note: @@ -1350,6 +1762,7 @@ def __call__( http_options = ( _BaseGrafeasRestTransport._BaseGetOccurrenceNote._get_http_options() ) + request, metadata = self._interceptor.pre_get_occurrence_note( request, metadata ) @@ -1364,6 +1777,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 grafeas_v1.GrafeasClient.GetOccurrenceNote", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "GetOccurrenceNote", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = GrafeasRestTransport._GetOccurrenceNote._get_response( self._host, @@ -1384,7 +1824,29 @@ def __call__( pb_resp = grafeas.Note.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_occurrence_note(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = grafeas.Note.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 grafeas_v1.GrafeasClient.get_occurrence_note", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "GetOccurrenceNote", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListNoteOccurrences( @@ -1421,7 +1883,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]]] = (), ) -> grafeas.ListNoteOccurrencesResponse: r"""Call the list note occurrences method over HTTP. @@ -1432,8 +1894,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: ~.grafeas.ListNoteOccurrencesResponse: @@ -1445,6 +1909,7 @@ def __call__( http_options = ( _BaseGrafeasRestTransport._BaseListNoteOccurrences._get_http_options() ) + request, metadata = self._interceptor.pre_list_note_occurrences( request, metadata ) @@ -1457,6 +1922,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 grafeas_v1.GrafeasClient.ListNoteOccurrences", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "ListNoteOccurrences", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = GrafeasRestTransport._ListNoteOccurrences._get_response( self._host, @@ -1477,7 +1969,31 @@ def __call__( pb_resp = grafeas.ListNoteOccurrencesResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_note_occurrences(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = grafeas.ListNoteOccurrencesResponse.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 grafeas_v1.GrafeasClient.list_note_occurrences", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "ListNoteOccurrences", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListNotes(_BaseGrafeasRestTransport._BaseListNotes, GrafeasRestStub): @@ -1512,7 +2028,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]]] = (), ) -> grafeas.ListNotesResponse: r"""Call the list notes method over HTTP. @@ -1522,8 +2038,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: ~.grafeas.ListNotesResponse: @@ -1531,6 +2049,7 @@ def __call__( """ http_options = _BaseGrafeasRestTransport._BaseListNotes._get_http_options() + request, metadata = self._interceptor.pre_list_notes(request, metadata) transcoded_request = ( _BaseGrafeasRestTransport._BaseListNotes._get_transcoded_request( @@ -1545,6 +2064,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 grafeas_v1.GrafeasClient.ListNotes", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "ListNotes", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = GrafeasRestTransport._ListNotes._get_response( self._host, @@ -1565,7 +2111,29 @@ def __call__( pb_resp = grafeas.ListNotesResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_notes(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = grafeas.ListNotesResponse.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 grafeas_v1.GrafeasClient.list_notes", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "ListNotes", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _ListOccurrences( @@ -1602,7 +2170,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]]] = (), ) -> grafeas.ListOccurrencesResponse: r"""Call the list occurrences method over HTTP. @@ -1612,8 +2180,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: ~.grafeas.ListOccurrencesResponse: @@ -1623,6 +2193,7 @@ def __call__( http_options = ( _BaseGrafeasRestTransport._BaseListOccurrences._get_http_options() ) + request, metadata = self._interceptor.pre_list_occurrences( request, metadata ) @@ -1639,6 +2210,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 grafeas_v1.GrafeasClient.ListOccurrences", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "ListOccurrences", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = GrafeasRestTransport._ListOccurrences._get_response( self._host, @@ -1659,7 +2257,29 @@ def __call__( pb_resp = grafeas.ListOccurrencesResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_occurrences(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = grafeas.ListOccurrencesResponse.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 grafeas_v1.GrafeasClient.list_occurrences", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "ListOccurrences", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _UpdateNote(_BaseGrafeasRestTransport._BaseUpdateNote, GrafeasRestStub): @@ -1695,7 +2315,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]]] = (), ) -> grafeas.Note: r"""Call the update note method over HTTP. @@ -1705,8 +2325,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: ~.grafeas.Note: @@ -1716,6 +2338,7 @@ def __call__( """ http_options = _BaseGrafeasRestTransport._BaseUpdateNote._get_http_options() + request, metadata = self._interceptor.pre_update_note(request, metadata) transcoded_request = ( _BaseGrafeasRestTransport._BaseUpdateNote._get_transcoded_request( @@ -1734,6 +2357,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 grafeas_v1.GrafeasClient.UpdateNote", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "UpdateNote", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = GrafeasRestTransport._UpdateNote._get_response( self._host, @@ -1755,7 +2405,29 @@ def __call__( pb_resp = grafeas.Note.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_note(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = grafeas.Note.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 grafeas_v1.GrafeasClient.update_note", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "UpdateNote", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp class _UpdateOccurrence( @@ -1793,7 +2465,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]]] = (), ) -> grafeas.Occurrence: r"""Call the update occurrence method over HTTP. @@ -1803,8 +2475,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: ~.grafeas.Occurrence: @@ -1816,6 +2490,7 @@ def __call__( http_options = ( _BaseGrafeasRestTransport._BaseUpdateOccurrence._get_http_options() ) + request, metadata = self._interceptor.pre_update_occurrence( request, metadata ) @@ -1838,6 +2513,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 grafeas_v1.GrafeasClient.UpdateOccurrence", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "UpdateOccurrence", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + # Send the request response = GrafeasRestTransport._UpdateOccurrence._get_response( self._host, @@ -1859,7 +2561,29 @@ def __call__( pb_resp = grafeas.Occurrence.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_occurrence(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = grafeas.Occurrence.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 grafeas_v1.GrafeasClient.update_occurrence", + extra={ + "serviceName": "grafeas.v1.Grafeas", + "rpcName": "UpdateOccurrence", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) return resp @property diff --git a/packages/grafeas/samples/generated_samples/snippet_metadata_grafeas.v1.json b/packages/grafeas/samples/generated_samples/snippet_metadata_grafeas.v1.json index 94c1606b2cc5..290215d3171d 100644 --- a/packages/grafeas/samples/generated_samples/snippet_metadata_grafeas.v1.json +++ b/packages/grafeas/samples/generated_samples/snippet_metadata_grafeas.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "grafeas", - "version": "1.12.1" + "version": "0.1.0" }, "snippets": [ { @@ -51,7 +51,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.types.BatchCreateNotesResponse", @@ -135,7 +135,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.types.BatchCreateNotesResponse", @@ -220,7 +220,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.types.BatchCreateOccurrencesResponse", @@ -304,7 +304,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.types.BatchCreateOccurrencesResponse", @@ -393,7 +393,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.types.Note", @@ -481,7 +481,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.types.Note", @@ -566,7 +566,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.types.Occurrence", @@ -650,7 +650,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.types.Occurrence", @@ -731,7 +731,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_note" @@ -808,7 +808,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_note" @@ -886,7 +886,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_occurrence" @@ -963,7 +963,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "shortName": "delete_occurrence" @@ -1041,7 +1041,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.types.Note", @@ -1121,7 +1121,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.types.Note", @@ -1202,7 +1202,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.types.Note", @@ -1282,7 +1282,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.types.Note", @@ -1363,7 +1363,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.types.Occurrence", @@ -1443,7 +1443,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.types.Occurrence", @@ -1528,7 +1528,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.services.grafeas.pagers.ListNoteOccurrencesAsyncPager", @@ -1612,7 +1612,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.services.grafeas.pagers.ListNoteOccurrencesPager", @@ -1697,7 +1697,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.services.grafeas.pagers.ListNotesAsyncPager", @@ -1781,7 +1781,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.services.grafeas.pagers.ListNotesPager", @@ -1866,7 +1866,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.services.grafeas.pagers.ListOccurrencesAsyncPager", @@ -1950,7 +1950,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.services.grafeas.pagers.ListOccurrencesPager", @@ -2039,7 +2039,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.types.Note", @@ -2127,7 +2127,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.types.Note", @@ -2216,7 +2216,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.types.Occurrence", @@ -2304,7 +2304,7 @@ }, { "name": "metadata", - "type": "Sequence[Tuple[str, str]" + "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], "resultType": "grafeas.grafeas_v1.types.Occurrence", diff --git a/packages/grafeas/tests/unit/gapic/grafeas_v1/test_grafeas.py b/packages/grafeas/tests/unit/gapic/grafeas_v1/test_grafeas.py index 13faaea9b42b..4cb82f78f551 100644 --- a/packages/grafeas/tests/unit/gapic/grafeas_v1/test_grafeas.py +++ b/packages/grafeas/tests/unit/gapic/grafeas_v1/test_grafeas.py @@ -5620,6 +5620,7 @@ def test_get_occurrence_rest_required_fields(request_type=grafeas.GetOccurrenceR 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_occurrence(request) @@ -5665,6 +5666,7 @@ def test_get_occurrence_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_occurrence(**mock_args) @@ -5804,6 +5806,7 @@ def test_list_occurrences_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_occurrences(request) @@ -5859,6 +5862,7 @@ def test_list_occurrences_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_occurrences(**mock_args) @@ -6049,6 +6053,7 @@ def test_delete_occurrence_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_occurrence(request) @@ -6092,6 +6097,7 @@ def test_delete_occurrence_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_occurrence(**mock_args) @@ -6224,6 +6230,7 @@ def test_create_occurrence_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_occurrence(request) @@ -6278,6 +6285,7 @@ def test_create_occurrence_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_occurrence(**mock_args) @@ -6414,6 +6422,7 @@ def test_batch_create_occurrences_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.batch_create_occurrences(request) @@ -6468,6 +6477,7 @@ def test_batch_create_occurrences_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.batch_create_occurrences(**mock_args) @@ -6605,6 +6615,7 @@ def test_update_occurrence_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_occurrence(request) @@ -6660,6 +6671,7 @@ def test_update_occurrence_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_occurrence(**mock_args) @@ -6795,6 +6807,7 @@ def test_get_occurrence_note_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_occurrence_note(request) @@ -6840,6 +6853,7 @@ def test_get_occurrence_note_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_occurrence_note(**mock_args) @@ -6968,6 +6982,7 @@ def test_get_note_rest_required_fields(request_type=grafeas.GetNoteRequest): 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_note(request) @@ -7013,6 +7028,7 @@ def test_get_note_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_note(**mock_args) @@ -7148,6 +7164,7 @@ def test_list_notes_rest_required_fields(request_type=grafeas.ListNotesRequest): 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_notes(request) @@ -7203,6 +7220,7 @@ def test_list_notes_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_notes(**mock_args) @@ -7389,6 +7407,7 @@ def test_delete_note_rest_required_fields(request_type=grafeas.DeleteNoteRequest 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_note(request) @@ -7432,6 +7451,7 @@ def test_delete_note_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_note(**mock_args) @@ -7569,6 +7589,7 @@ def test_create_note_rest_required_fields(request_type=grafeas.CreateNoteRequest 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_note(request) @@ -7631,6 +7652,7 @@ def test_create_note_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_note(**mock_args) @@ -7767,6 +7789,7 @@ def test_batch_create_notes_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.batch_create_notes(request) @@ -7821,6 +7844,7 @@ def test_batch_create_notes_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.batch_create_notes(**mock_args) @@ -7953,6 +7977,7 @@ def test_update_note_rest_required_fields(request_type=grafeas.UpdateNoteRequest 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_note(request) @@ -8008,6 +8033,7 @@ def test_update_note_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_note(**mock_args) @@ -8152,6 +8178,7 @@ def test_list_note_occurrences_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_note_occurrences(request) @@ -8207,6 +8234,7 @@ def test_list_note_occurrences_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_note_occurrences(**mock_args) @@ -9109,6 +9137,7 @@ def test_get_occurrence_rest_bad_request(request_type=grafeas.GetOccurrenceReque 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_occurrence(request) @@ -9148,6 +9177,7 @@ def test_get_occurrence_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_occurrence(request) # Establish that the response is the type that we expect. @@ -9188,6 +9218,7 @@ def test_get_occurrence_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 = grafeas.Occurrence.to_json(grafeas.Occurrence()) req.return_value.content = return_value @@ -9230,6 +9261,7 @@ def test_list_occurrences_rest_bad_request(request_type=grafeas.ListOccurrencesR 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_occurrences(request) @@ -9265,6 +9297,7 @@ def test_list_occurrences_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_occurrences(request) # Establish that the response is the type that we expect. @@ -9301,6 +9334,7 @@ def test_list_occurrences_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 = grafeas.ListOccurrencesResponse.to_json( grafeas.ListOccurrencesResponse() ) @@ -9347,6 +9381,7 @@ def test_delete_occurrence_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_occurrence(request) @@ -9377,6 +9412,7 @@ def test_delete_occurrence_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_occurrence(request) # Establish that the response is the type that we expect. @@ -9411,6 +9447,7 @@ def test_delete_occurrence_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 = grafeas.DeleteOccurrenceRequest() metadata = [ @@ -9451,6 +9488,7 @@ def test_create_occurrence_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.create_occurrence(request) @@ -9927,6 +9965,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_occurrence(request) # Establish that the response is the type that we expect. @@ -9969,6 +10008,7 @@ def test_create_occurrence_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 = grafeas.Occurrence.to_json(grafeas.Occurrence()) req.return_value.content = return_value @@ -10013,6 +10053,7 @@ def test_batch_create_occurrences_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.batch_create_occurrences(request) @@ -10046,6 +10087,7 @@ def test_batch_create_occurrences_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.batch_create_occurrences(request) # Establish that the response is the type that we expect. @@ -10083,6 +10125,7 @@ def test_batch_create_occurrences_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 = grafeas.BatchCreateOccurrencesResponse.to_json( grafeas.BatchCreateOccurrencesResponse() ) @@ -10129,6 +10172,7 @@ def test_update_occurrence_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_occurrence(request) @@ -10605,6 +10649,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.update_occurrence(request) # Establish that the response is the type that we expect. @@ -10647,6 +10692,7 @@ def test_update_occurrence_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 = grafeas.Occurrence.to_json(grafeas.Occurrence()) req.return_value.content = return_value @@ -10691,6 +10737,7 @@ def test_get_occurrence_note_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.get_occurrence_note(request) @@ -10730,6 +10777,7 @@ def test_get_occurrence_note_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_occurrence_note(request) # Establish that the response is the type that we expect. @@ -10772,6 +10820,7 @@ def test_get_occurrence_note_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 = grafeas.Note.to_json(grafeas.Note()) req.return_value.content = return_value @@ -10814,6 +10863,7 @@ def test_get_note_rest_bad_request(request_type=grafeas.GetNoteRequest): 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_note(request) @@ -10853,6 +10903,7 @@ def test_get_note_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_note(request) # Establish that the response is the type that we expect. @@ -10893,6 +10944,7 @@ def test_get_note_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 = grafeas.Note.to_json(grafeas.Note()) req.return_value.content = return_value @@ -10935,6 +10987,7 @@ def test_list_notes_rest_bad_request(request_type=grafeas.ListNotesRequest): 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_notes(request) @@ -10970,6 +11023,7 @@ def test_list_notes_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_notes(request) # Establish that the response is the type that we expect. @@ -11006,6 +11060,7 @@ def test_list_notes_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 = grafeas.ListNotesResponse.to_json(grafeas.ListNotesResponse()) req.return_value.content = return_value @@ -11048,6 +11103,7 @@ def test_delete_note_rest_bad_request(request_type=grafeas.DeleteNoteRequest): 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_note(request) @@ -11078,6 +11134,7 @@ def test_delete_note_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_note(request) # Establish that the response is the type that we expect. @@ -11110,6 +11167,7 @@ def test_delete_note_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 = grafeas.DeleteNoteRequest() metadata = [ @@ -11148,6 +11206,7 @@ def test_create_note_rest_bad_request(request_type=grafeas.CreateNoteRequest): 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_note(request) @@ -11447,6 +11506,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_note(request) # Establish that the response is the type that we expect. @@ -11487,6 +11547,7 @@ def test_create_note_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 = grafeas.Note.to_json(grafeas.Note()) req.return_value.content = return_value @@ -11531,6 +11592,7 @@ def test_batch_create_notes_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.batch_create_notes(request) @@ -11564,6 +11626,7 @@ def test_batch_create_notes_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.batch_create_notes(request) # Establish that the response is the type that we expect. @@ -11601,6 +11664,7 @@ def test_batch_create_notes_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 = grafeas.BatchCreateNotesResponse.to_json( grafeas.BatchCreateNotesResponse() ) @@ -11645,6 +11709,7 @@ def test_update_note_rest_bad_request(request_type=grafeas.UpdateNoteRequest): 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_note(request) @@ -11944,6 +12009,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.update_note(request) # Establish that the response is the type that we expect. @@ -11984,6 +12050,7 @@ def test_update_note_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 = grafeas.Note.to_json(grafeas.Note()) req.return_value.content = return_value @@ -12028,6 +12095,7 @@ def test_list_note_occurrences_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_note_occurrences(request) @@ -12063,6 +12131,7 @@ def test_list_note_occurrences_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_note_occurrences(request) # Establish that the response is the type that we expect. @@ -12101,6 +12170,7 @@ def test_list_note_occurrences_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 = grafeas.ListNoteOccurrencesResponse.to_json( grafeas.ListNoteOccurrencesResponse() ) diff --git a/scripts/client-post-processing/unique-grafeas-client.yaml b/scripts/client-post-processing/unique-grafeas-client.yaml index 7e4a3403eec4..26e2d17ed925 100644 --- a/scripts/client-post-processing/unique-grafeas-client.yaml +++ b/scripts/client-post-processing/unique-grafeas-client.yaml @@ -1608,6 +1608,10 @@ replacements: \ # 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\( @@ -1669,6 +1673,29 @@ replacements: \ always_use_jwt_access=True, \ 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 `grafeas_v1.GrafeasClient`.", + \ extra=\{ + \ "serviceName": "grafeas.v1.Grafeas", + \ "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": "grafeas.v1.Grafeas", + \ "credentialsType": None, + \ \}, + \ \) after: | \n def __init__(